你们好,我叫李伟涛,来自凹凸实验室。今天跟你们分享的主题是用 React 开发小程序的探索之路 。前端
在目前市面上已经有很是多的小程序开发框架,其中的佼佼者如 wepy 以及 mpvue ,他们都是很是优秀的小程序开发框架。可是它们都有一个共同的特色,都是经过类 vue 语法的小程序开发框架。这点对于国内一些 react 的开发者来讲就显得有点遗憾了。vue
咱们团队在去年就总体转入了 react 开发阵营,对于咱们团队来讲, react 会更加熟悉一些。因此咱们一直在探索如何用 react 开发小程序,前端时间咱们开源了一个框架,叫作 Taro 。本次也会围绕这个,来分享 探索使用 react 开发小程序。主要包含如下五个部份内容:react
开发小程序由三部分组成,这三大部分都是由四种类型文件,以下图所示:git
咱们以 JS 文件为例:github
咱们在写原生小程序的时候,这两份代码是很是常见的。 它们都是借助函数工厂类的方式去构建页面以及组件。 在小程序中的一大特点就是使用字符串模板的形式来编写界面,如图:小程序
以上就是一些小程序官方写法上的一些约定,但也是这些约定,让开发者存在一些开发上的痛点,这些痛点主要集中在:微信小程序
在开发体验上,代码组织稍显复杂。 当组件和页面愈来愈多,项目愈来愈庞大的时候开发成本就会显得有点高,其次就是编码体验不够顺畅,以下图:性能优化
页面或者组件没法被继承的时候,咱们在实现一些功能的时候会受到一些限制 ,同时小程序自己提供了一些 API ,可是却没有提供一个跟编辑器很好结合的东西,当咱们在使用这些 API 的时候缺少智能提示。 其次就是字符串模板稍显孱弱。例如 :微信
当咱们实现一个日期格式化的时候,点击的时候没法传参,还有就是直接写一个格式化函数是没法运行的,咱们须要借助 wxs 这样的一些工具去实现这样的一个功能,可是这样是很是麻烦的。 还有就是小程序的代码规范并非很统一,以 Button 组件为例:架构
一些属性参数都是有很大的差别的。 其次就是缺少统一的自动化编译处理,致使没法直接在小程序中直接使用一些 新的 ES 语法,以及 SASS 、 LESS 来书写样式代码。
在性能瓶颈上面,小程序的总体架构是这样的:
分为视图层和逻辑层,这两个层之间是有一个特定的通讯方式的,当咱们在调用 setData 去更新视图的时候,小程序首先把你传入的数据 使用 JSON.stringify 进行序列化,以后拼接成一段可执行的 JS 脚本,最后运行。在这样的一层通讯机制上,致使去调用 setData 的去更新视图的时候成本很是之高。因此小程序官方也是提供了一些对于性能优化上的提示
针对以上的痛点和限制,业界也有一些优秀的解决方案,诸如 mpvue, wepy, 可是它们都是类 vue 的开发框架。正如前面所说,这样子的话对于咱们团队或者使用 react 的开发者有点遗憾。
使用 react 来开发应用带来的的一些好处:
react 和 小程序是有一些共同特色的
正由于这样,也是更加想用 react 来开发小程序。 通过进一步的研究发现,小程序和 react 之间的差别是很是大的 主要是因为三大块的差别:
JS 代码对比:
生命周期对比:
模板对比:
这么大的差别致使咱们想用 react 来开发小程序的难度很是之大,因此咱们应该怎么使用 react 来开发小程序呢? 仔细思考一下咱们的需求,咱们是但愿经过 react 语法的代码来开发小程序,那么其中的核心工做就是将 react 代码经过某种转换操做,变成小程序能够运行的代码。这样一种在两种语法之间转换的这种操做其实就涉及到一个编译原理。 编译原理的一个大体过程大概如图所示:
其中最核心的就是把源代码编译成 AST (虚拟语法树),而后将 AST 进行转换操做得出目标代码。 在 JS 中,它是有本身的 AST 规范来进行定义,这个规范就是 ESTree Spac
在 JS 领域中,有很是多的 JS 的解析器,来帮你把代码转换成语法树的工具,其中最广为应用的就是 BABEL。
它提供了一套很是完成的工具来帮你作代码转换。 从源代码到语义分析,咱们均可以借助 BABEL 来进行转换。 在这以后的语法树转换、代码优化仍是须要们本身来进行的,这一部分也是很是繁琐且复杂。
在 Taro 中,咱们经过在编译时处理以及运行时适配来转换成小程序代码,
编译时的处理:
在 JSX 中,一般有各类各样的写法:
这致使在编译的时候很是复杂,须要作大量的测试用例来保证转换是正常的。
代码编译出来时候,仍是不能只在小程序上运行的,小程序须要一个运行时的适配来帮助咱们把代码运行在小程序里面。 运行时的框架主要是一些生命周期的转换适配,还有一些事件处理。
仅仅这些是不够的,若是真正须要投入开发使用仍是有点差距的。这个时候我么你须要一个开发工具来进行配合。
同时,Taro 来提供了一些贴心的功能,来帮助咱们得到良好的开发体验
开源之初,因为种种缘由,Taro 的微信小程序端组件化采用的是小程序 <template />
标签来实现的,利用小程序 <template />
标签的特性,将组件 JS 文件编译成 JS + WXML 模板,在父组件(页面)的模板中经过 <template />
标签引用子组件的 WXML 模板来进行拼接,从而达到组件化的目的。 实践证实,Template 模板方案是一个失败的组件化方案,Taro 开源初期的 Bug 主要来源于此。由于这一方案将 JS 逻辑与模板拆分开了,须要手工来保证 JS 与模板中数据一致,这样在循环组件渲染、组件多重嵌套的状况下,要保证组件正确渲染与 props 正确传递的难度很是大,实现的成本也很是高。并且,囿于小程序 <template />
标签的缺陷,一些功能(例如自定义组件包含子元素,等)没法实现。
因此,在通过艰辛的探索与实践以后,咱们采用了小程序原生组件化来做为 Taro 的小程序端组件化方案,而且经过一些处理,绕开了小程序组件化的诸多限制,为 Taro 的稳定性打下了坚实基础,并带来了如下好处:
其中有个重要的改进,小程序端性能的优化
最初的版本中,仅仅是对小程序 setData 作了一次异步封装,最终调用 setData 更新的时候仍是传入了完整数据。
以前咱们讲到过在频繁的调用 setData 和 数据量很是大的时候,小程序就会变得异常卡顿,性能不好。
Taro 在框架级别帮助开发者进行了优化,在 setData 以前进行了一次数据 Diff,找到数据的最小更新路径,而后再使用此路径来进行更新
除此以外,咱们还作了更多
从 开源 到如今,Taro 一共经历了 1800 余次提交,平均天天近 20 次,最多的一天达 30 次。每一次提交都是进步,每一次提交都让 Taro 更增强大。通过这么屡次迭代以后,已经让 Taro 得到重生,尤为是小程序组件化重构完成以后,Taro 从旧版架构的泥潭中一跃而出,成为更加健壮的开发框架。 在咱们本身不断反思、优化的同时,也积极融入开源社区,依托社区的力量去建设 Taro。 Taro 到目前为止,一共收到了 500 余个 ISSUES,已关闭近 400 个,正是由于这些 ISSUES ,让咱们不断意识到 Taro 的不足,让咱们知道如何去进行迭代。 同时,咱们也一直鼓励社区的开发者积极提 PR,一个优秀的开源项目须要依靠整个社区的力量才能完善起来,到目前为止,一共收到了 120 余个 PR,已几近所有合入,这些 PR 为 Taro 注入了许多新鲜血液,让 Taro 更加健壮,咱们也指望能有更多的开发者能够加入进来,一块儿来让 Taro 更加美好。 在 GitHub 上交流之余,咱们也为开发者们开通了官方微信群供你们一块儿讨论 Taro 与技术,目前已有超过 1700 位开发者在关注、使用 Taro ,期待更多开发者的加入。
在开源期间,随着 Taro 的逐步完善,愈来愈多的开发者加入到 Taro 的使用、开发中,产生了更多更优秀的使用案例。
Taro 的发展离不开广大开源爱好者的帮助,在此特别鸣谢广大 Taro 的使用者以及 Taro 主要贡献者
Taro 将会继续保持迭代,目前已经规划了以下重要功能:
在编译时与运行时提供代码诊断的功能,分析代码优劣,断定代码写法是否规范,以便帮助开发者规避一些因为写法带来的问题。 同时将提供一套测试方案,方便开发者书写并运行组件测试用例,提高代码质量。
目前 Taro 只能一次调试一个端,这对于开发多端应用来讲效率略低,因此,计划提供微信小程序/ H5 / React Native 端同时调试的功能,能够一键启动多端同时编译,从而得到多端同步预览。
目前已支持 Taro 代码到小程序代码、 H5 代码的转换,在将来,将提供逆向转换功能,帮助开发者将本来就存在的小程序/H5 项目直接转换成 Taro 项目,从而让本来只能运行在一端的项目得到多端运行的能力,下降开发者的重构成本。
Taro 是遵循 React 语法规范的,可是 React 一直在迭代在变化,Taro 做为 React 的追随者也将会保持与 React 新特性同步,让 Taro 最大程度接近 React 开发体验。
目前 Taro 已经完成了快应用端组件库与 API 的适配,快应用端的文件转换与模板转换也正在开发中,不久的未来就会发布支持快应用端转换的版本。 支付宝小程序与百度智能小程序支持 已预研支付宝小程序与百度智能小程序转换的可行性,即将进入开发。
目前 Taro 是依靠开发者手工编写代码来得到多端应用的,Taro 将来计划提供一个多端可视化拖拽搭建的功能,能够经过拖拽组件的方式来生成多端应用。 同时,Taro 将联合各大公司小程序开发团队,推出丰富的行业模板,为各行业应用可视化搭建提供完整的解决方案。
在开源之初,Taro 一直处于封闭的状态,没有适配的 UI 库,也没法使用第三方组件库,而这些对开发效率的桎梏很是严重,社区内对此反馈较多。因此,咱们基于 Taro 推出了首个能够跨多端使用的多端 UI 库 Taro UI,目前已经支持了微信小程序与 H5 端,不久以后将完成 React Native 端的适配,能够同步提供给 React Native 端使用。