“AI 技术+人才”如何成为企业增长新引擎?戳此了解>>> 了解详情
写点什么

基于 TypeScript 的 Weex 优化实践

  • 2020-08-02
  • 本文字数:4274 字

    阅读完需:约 14 分钟

基于 TypeScript 的 Weex 优化实践

一、背景

Weex 作为一种成熟的跨平台程序框架被运用到许多产品中,有赞也不例外。有赞零售移动端团队从 2018 年就开始使用 Weex 构建页面,据不完全统计,有赞零售移动端有超过 300 个页面使用到了 Weex 开发!显然,这是一个巨大的开发工程,同时我们也发现基于 JavaScript 的 Weex 开发给我们带来了诸多痛点:


  • 缺少类型约束,编程时代码提示全凭记忆,要拓展新功能也束手束脚。

  • 手误写错某个变量名,只能在联调、测试阶段才能发现。

  • 面对复杂业务逻辑,代码层面可控性、扩展性较差。

  • 总会遇到 xxxisundefined 的空指针问题。


这些问题我们都在 TypeScript 找到了答案。

二、什么是 TypeScript

TypeScript 是微软开源的编程语言,它建立在 JavaScript 的基础上,是 JavaScript 的超集,可以编译成 JavaScript。它有以下特点:


1.始于 JavaScript,归于 JavaScript


TypeScript 从今天数以百万计的 JavaScript 开发者所熟悉的语法和语义中拓生而来,所使用的是通用的 JavaScript 代码,包括流行的 JavaScript 库,从 JavaScript 代码中调用 TypeScript 代码轻而易举。TypeScript 可以编译出纯净、 简洁的 JavaScript 代码,并能运行在任何支持 ES3 及以上的 JavaScript 引擎中。


2.强大的工具构建


类型允许 JavaScript 开发者在开发 JavaScript 应用程序时使用高效的开发工具和常用操作,比如静态检查和代码重构。类型是可选的,类型推断让一些类型的注释与你的代码的静态验证有很大的不同。类型让你能自主定义软件组件之间的接口和洞察现有 JavaScript 库的行为.


3.进阶的 JavaScript


TypeScript 提供最新的和不断发展的 JavaScript 特性,包括那些来自 ES2015 和未来提案中的特性,比如异步功能和装饰器,以帮助建立健壮的组件。

三、为什么要使用 TypeScript

1. 降低维护成本,提升健壮性、稳定性

1)代码即文档,好的接口、函数定义可直接代替文档,代码可读性更高。


2)静态类型检查,提早发现问题代码。

2. 提高开发效率

1)对代码重构和补全提示友好。


2)多人协作降低沟通成本,不再需要频繁阅读文档或细究实现细节。


3)类型可选,让你在不编写额外代码的情况下获得很多功能。


4)有很多先进的高级特性可以使用。

3. 成熟度高

1)编辑器或 IDE 集成度高。


2)社区庞大,周边工具丰富。


3)最受欢迎的编程语言排行榜中已跃升至第 10 名,话题度高。


4)多个团队全面使用 TypeScript 重构代码(Vue、React 、Angular),甚至连 Facebook 自家的产品(Jest、Yarn 等等)都在从 Flow 向 TypeScript 迁移。


4. 接入成本低

1)几乎没有接入成本,对当前工程改造小。


2)可以和 JavaScript 混合开发、编译成 JavaScript 在各端运行。


3)支持多种工具链。

5. 学习成本低

几乎没有学习成本,移动端各自开发的语言本身就有类型系统,并且 Swift、kotlin 也有可选类型,语法也和 TypeScript 类似。

四、如何使用 TypeScript 进行 Weex 开发

随着 Vue2.x 对 TypeScript 的支持,Weex 也能快速接入 TypeScript。同时 Vue3.0 将使用 TypeScript 重写,重写后的 Vue3.0 更能发挥 TypeScript 的特点。

1.接入 TypeScript

虽然市面上关于 Weex 支持 TypeScript 的资料比较少,但关于 Vue 如何接入 TypeScript 的文章铺天盖地,这里做个简单总结:


  • 添加 TypeScript 依赖,根据所需升级相关依赖或者有影响的包(当使用第三方库时,我们需要引用它的声明文件,才能获得对应的代码补全、接口提示等功能)。

  • ts-loader 可选,如果之前的项目工程对 Babel 依赖比较重,可以保留 babel-loader(Babel>=7)。Babel 已和 TypeScript 官方展开了合作,解决了部分之前不能被正常编译的问题。或者通过使用两个编译器,搭配 ts-loaderbabel-loader 来接入 TypeScript。

  • 添加 tsconfig.json ,并加入相关你需要的自定义配置。

  • 官方对 ESLint 做了支持,提供了解析 TypeScript 代码的编译器,可以把语法树转成 ESLint 所期望对 ESTree,使用 @typescript-eslint 即可。

  • 添加必要的声明文件,Weex 目前还没有官方的声明文件,大家可按需添加。

2.声明文件

Weex 官方目前没有对 TypeScript 提供优秀的支持,需要自行添加声明文件。


比如:


const platform = weex.config.env.platform
复制代码


在 TypeScript 中,编译器并不知道 Weex 是什么东西。这时我们需要对其声明


声明文件必需以 .d.ts 为后缀。一般来说,TypeScript 会解析项目中所有的 *.ts 文件,当然也包含以.d.ts结尾的文件。


例:weex.d.ts


declare interface IWeexGlobal {    config: {        platform: 'Android' | 'iOS' | 'Web'    }}declare const weex: IWeexGlobal
复制代码


Typescript 默认不能识别 .vue 文件,导致在引用时,会提示加载错误。所以需要自己新建一个 .d.ts 声明文件文件添加以下内容。这是为了告诉 Typescript 以 .vue 结尾的导入的任何东西都与 Vue 构造函数本身具有相同的形状。注意引用 vue 组件时需要补全 .vue


例:vue.d.ts


declare module '*.vue' {    import Vue from 'vue'    export default Vue}
复制代码


关于声明文件详细内容,具体可参考官方文档。

3.类组件

要让 TypeScript 正确推断 Vue 组件选项中的类型,需要使用类组件。在 Vue 2.x 中,通常使用基于 Vue Class Component 装饰器来用使用类组件。


Vue Class Component 对 Vue 组件进行了一层封装,让 Vue 组件语法在结合了 TypeScript 语法之后更加扁平化,代码可读性更高。


使用组类组件有以下差异:


  • @Component 修饰符注明了此类为一个 Vue 组件

  • 初始数据可以直接声明为实例的 property

  • 计算属性可以直接使用 getter / setter

  • 组件方法也可以直接声明为实例的方法

  • 所有 Vue 生命周期也可以直接声明为实例方法,但是你不能在实例本身上调用它们。声明自定义方法时,应避免使用这些保留名称

  • 其他接口描述对象可以传递给装饰器函数或者 Vue.extend



其他接口描述对象在类组件的使用:



TypeScript 的类组件和 JavaScript 的接口描述组件导出有些差异:


  • 类组件导出的是 Vue 类

  • 接口描述组件导出的是 ComponentOptions接口


所以在入口文件对 Vue 进行初始化上也会有些区别:


4.装饰器

TypeScript 支持装饰器这一特性,Javascript 里的装饰器目前处在建议征集的第二阶段。若要使用装饰器特性,需要在 tsconfig.json 里启用 experimentalDecorators 编译器选项。装饰器的好处如下:


1)使语法更加扁平化。


2)对业务代码无侵入。


3)解耦业务逻辑、辅助功能逻辑。


除了上节提到的 @ComponentVue Property DecoratorVuex Class 提供了更多的装饰器用于使用。装饰器可以用于修饰类、方法和属性等。

Vue Property Decorator

  • @Prop

  • @PropSync

  • @Model

  • @Watch

  • @Provide

  • @Inject

  • @ProvideReactive

  • @InjectReactive

  • @Emit

  • @Ref

  • @Component (由 vue-class-component 提供)


对常用对 @Prop@Watch 举个例:



关于其他装饰器如何使用,具体参考官方文档。

Vuex Class

  • @State

  • @Getter

  • @Action

  • @Mutation


关于如何使用,具体参考官方文档。

开发工具

1) Visual Studio CodeWeb Storm 都能做到开箱即用,不需要装配额外的插件。


2)对 ZWeex ToolKit 扩展能力,目前已经支持了创建 TypeScript 的页面

五、落地 TypeScript 提升系统稳定性

我们来对之前遇到的问题做个拆解,看看 TypeScript 是如何帮我们解决痛点。

1.减少 Bug

1)类型错误

TypeScript 的类型保护、联合类型、类型推导等特性,可以避免发生低级类型错误问题。比如在开发中约定函数的参数是 number 数字类型,如果使用时不慎使用了 string 类型的参数,那么 IDE 会有 error 警告并会在编译时报错。



2)空指针

TypeScript 会进行严格非空检查可以帮助我们避免空指针问题。


比如函数的参数定义是允许出现空指针的情况,那么在使用这些不安全的参数时,IDE 和编译器都会提醒你这块儿地方注意了,如果没有处理边界会给予提示。




添加了判断空指针进行处理异常边界之后,可以通过编译。


3)原生 module 类型约束

有赞零售使用有近 20 个原生 module,在之前开发过程中因为没有类型约束出现过不少写错 module/方法/参数名、使用错参数类型的情况。使用 TypeScript 的类型声明可以解决这些问题。


举个例子,有以下几个原生 module,我们对其类型声明


declare interface IWeexNativeModules {    foo: {        fun(a: number, b?: string): void    }
foo1: { oops(): void }
foo2: { oops(): void }}
复制代码


使用时,IDE 会有代码补全提示。如果写错 IDE 和编译器同样报错提示。



调用方法和参数时也会有类型约束。



通过使用 TypeScript 有效的避免了类型问题,减少 Bug 量。一篇伦敦大学和微软研究院联合署名的论文中提到:


通过对 Github 上开源项目的公开 Bug 统计发现:15% 的 Bug 都可以通过 TypeScript 来规避。

2.增强架构设计

TypeScript 比 JavaScript 多了接口、抽象类、范型、访问权限等,可以方便的落地架构设计。


面向接口(协议)编程在移动端应用是非常广泛的,使用 TypeScript 之后也可以进行一些架构设计。


之前我们在使用 Weex 进行开发时,往往会把所有逻辑代码往组件内部塞,使得组件后续维护起来非常麻烦。我们引入了和原生一样的规范:增加 Model、Service 层,通过工具自动生成相应目录结构,在开发中得到了非常好的约束。


效果

我们在 Q2 完成了 TypeScript 的迁移,开发效率显著提升、系统稳定性明显提高。


在对供应链单据页模版化的项目中,使用 TypeScript 进行了大范围的重构。我们发现联调期间的沟通显著减少,不需要频繁查阅接口文档,代码可读性更高了,节省了很多 debug 成本。在测试环节仅出现 个位数 的 Bug,发布线上之后也没问题发生。

六、平滑迁移 TypeScript

迁移工程不需要一蹴而就,你可以先用 JSDoc 注释现有的 JavaScript,然后迁移几个文件交由 TypeScript 检查,随着时间的推移,当你的代码库准备好了之后,代码库迁移到 TypeScript 自然就水到渠成了。

参考链接


本文转载自公众号有赞 coder(ID:youzan_coder)。


原文链接


https://mp.weixin.qq.com/s?__biz=MzAxOTY5MDMxNA==&mid=2455761139&idx=1&sn=a4cde112969fb5d3737ca4032bf12a53&chksm=8c6876d6bb1fffc05cb047840c618cb30e105442bd35bd06a765a045dc9698cc9a0f769e943c&scene=27#wechat_redirect


2020-08-02 14:042166

评论 2 条评论

发布
用户头像
巨大反馈
2020-08-02 16:45
回复
坚实的时刻
2020-08-02 16:45
回复
没有更多了
发现更多内容

一次系统调用时间过长追踪完整教程案例

AI乔治

Java Linux 架构

文档驱动开发模式在 AIMS 中的应用与实践

华为云开发者联盟

Web 代码 API 文档

开始的开始-可能是最早提交的28天写作活动作品

石君

28天写作

代码也能“杀”虫:此虫,真虫非Bug也

华为云开发者联盟

代码 华为云 modelarts

Spark HistoryServer日志解析&清理异常

笨小康

大数据 spark hdfs

LeetCode题解:111. 二叉树的最小深度,BFS,JavaScript,详细注释

Lee Chen

算法 大前端 LeetCode

VUE项目性能优化实践——通过懒加载提升页面响应速度

葡萄城技术团队

Vue

如何使用Eclipse内存分析工具定位内存泄露

Java老k

Java 内存泄露

从七日更,到28天写作挑战,我无法拒绝的原因

梁龙先森

大前端 编程语言 28天写作

边缘计算安全技术研究

华为云原生团队

云计算 大数据 云原生 边缘计算 华为云

Java中定时器Timer致命缺点(附学习方法)

叫练

学习 定时任务 多线程 定时器 技术学习

甲方日常 82

句子

随笔杂谈

不愧是Alibaba技术官:程序员必会的架构知识清单,如何让你技术上的提升面试时的丰收

Java架构之路

Java 程序员 架构 面试 编程语言

还在手动写数据库文档吗?试试这个工具,划水干活儿两不误!

我爱娃哈哈😍

数据库 文档生成

要想软件“一想之美”,UI测试少不了

华为云开发者联盟

软件 测试 华为云

ETL都没弄懂,谈什么大数据 ?我用一分钟给你整明白

智分析

ETL

Hive的调优你都知道那些?

大数据老哥

大数据 hadoop hive

软件界旷世之架:测试驱动开发(TDD)之争

华为云开发者联盟

软件 测试 TDD 代码 devcloud

数据中心“容灾”和“备份”的区别

【Mysql-InnoDB系列】InnoDB架构

程序员架构进阶

MySQL 架构 innodb 28天写作

一个正确的编程思维

程序员吴师兄

28天写作

新思科技网络安全研究中心发现Bouncy Castle中的漏洞

InfoQ_434670063458

新思科技 Bouncy Castle

价值 - 价值的底色(一)

石云升

读书笔记 投资 28天写作 价值

【CSS】CSS对大小写敏感吗?

德育处主任

28天写作

如果你听说过 Elastic Certified Engineer

escray

七日更 28天写作 死磕Elasticsearch 60天通过Elastic认证考试

volatile 关键字精讲

伯阳

Java volatile 后端 关键字 多线程与高并发

云算力矿机租赁挖矿APP系统开发|云算力矿机租赁挖矿软件开发

系统开发

CSS09 - 文本&背景属性

Mr.Cactus

html/css

俯瞰Dubbo全局,阅读源码前必须掌握这些!!

冰河

架构 分布式 微服务 dubbo 服务治理

如何使用Eclipse内存分析工具定位内存泄露

AI乔治

Java eclipse 架构

杜绝标题党,好的标题是成功的99%

xcbeyond

方法论 28天写作 写作技巧

基于 TypeScript 的 Weex 优化实践_开源_周佳敏_InfoQ精选文章