在 2018.6.7
我们对外开源了 多端统一开发框架——Taro
。
Taro 是一个多端统一开发框架,它支持使用 React 的开发方式来编写可以同时在微信小程序、Web 、React Native 等多个平台上运行的应用,帮助开发者提升开发效率,改善开发体验,降低多端研发成本。
自开源以来,Taro 一直广受业界关注,其原理与思想也得到了广泛开发者的认可,这对于我们来说无疑是一件令人振奋的事。但是由于初期 Taro 测试与实现方式的不足,导致在开源期间 Bug 较多,受到了一些质疑。为此,我们痛定思痛,积极接受了开源社区的意见与帮助,并努力探索提升 Taro 稳定性与性能的方式。经过不断地迭代完善,已经让 Taro 浴火重生。
1.0.0 真的来了
Taro 开源到现在 3 个月时间,累计发布 70 余日常版本及 20 余 Taro 1.0.0 的 beta
版本,经过近百个版本的迭代优化,我们亲身体会到 Taro 的 BUG 反馈越来越少,Taro 越来越健壮且完善,因此,我们有信心推出 1.0.0 正式版。
Taro 1.0.0 正式版在延续了之前版本优秀特性的同时,增加了更加丰富的特性与功能,并进行了多项小程序端/H5端的转换优化,同时带来了对 React Native 的转换支持。
全新的小程序组件化
开源之初,由于种种原因,Taro 的微信小程序端组件化采用的是小程序 <template />
标签来实现的,利用小程序 <template />
标签的特性,将组件 JS 文件编译成 JS + WXML 模板,在父组件(页面)的模板中通过 <template />
标签引用子组件的 WXML 模板来进行拼接,从而达到组件化的目的。
实践证明,Template
模板方案是一个失败的组件化方案,Taro 开源初期的 Bug 主要来源于此。因为这一方案将 JS 逻辑与模板拆分开了,需要手工来保证 JS 与模板中数据一致,这样在循环组件渲染、组件多重嵌套的情况下,要保证组件正确渲染与 props
正确传递的难度非常大,实现的成本也非常高。而且,囿于小程序 <template />
标签的缺陷,一些功能(例如自定义组件包含子元素,等)无法实现。
所以,在经过艰辛的探索与实践之后,我们采用了小程序原生组件化来作为 Taro 的小程序端组件化方案,并且通过一些处理,绕开了小程序组件化的诸多限制,为 Taro 的稳定性打下了坚实基础,并带来了以下好处:
- 小程序端组件化更加健壮
- 尽可能减少由于框架带来的性能问题
- 依托官方组件化,方便以后解锁更多可能
全面支持小程序生态
为了更好地帮助开发者使用 Taro 开发小程序,在 1.0.0
版本中,我们加强了对小程序生态的支持,主要提现在以下几个方面。
支持引用小程序端第三方组件库
受益于小程序组件化重构,我们在 Taro 中支持了直接引用小程序端第三方组件库,让 Taro 可以融入到小程序生态中,为开发者提供更多便利。
目前实测已经支持了如下知名第三方组件库
- echarts-for-weixin,ECharts 的微信小程序版本
- iview-weapp,iview 的微信小程序版本
- vant-weapp,轻量、可靠的小程序 UI 组件库
- wxParse,微信小程序富文本解析自定义组件,支持HTML及markdown解析
当然,Taro 不仅仅只支持上述组件库,只要是按原生小程序规范编写的组件库都能在 Taro 中正常使用。
支持 Taro 代码与原生小程序代码混写
与此同时,Taro 支持原生小程序代码与 Taro 代码混写,因此,可以使用 Taro 愉快地将旧的小程序项目慢慢地改造成 Taro 项目了。
支持小程序端分包加载以及插件引用
我们在 Taro 中也加入对原生小程序分包加载功能的支持,配置的方式与原生小程序基本一致,只需要在 app.js
入口文件中加入 subPackage
字段即可。
import Taro, { Component } from '@tarojs/taro'
class App extends Component {
config = {
pages: [
'pages/index',
'pages/logs'
],
subPackages: [
{
root: 'moduleA',
pages: [
'pages/rabbit',
'pages/squirrel'
]
}
]
}
}
同时,Taro 也支持了使用小程序的插件功能,可以在 Taro 中直接引用第三方的插件
import Taro, { Component } from '@tarojs/taro'
import { View } from '@tarojs/Components'
class PageA extends Component {
config = {
usingComponents: {
'hello-component': 'plugin://myPlugin/hello-component'
}
}
render () {
return (
<View>
<hello-component></hello-component>
</View>
)
}
}
小程序 setState 性能优化
在最初的开源版本中,小程序端 setState
仅仅是对小程序 setData
做了一次异步封装,最终调用 setData
更新的时候还是传入了完整数据。
但众所周知,小程序的视图层目前使用 WebView 作为渲染载体,而逻辑层是由独立的 JavascriptCore 作为运行环境,在架构上,WebView 和 JavascriptCore 都是独立的模块,并不具备数据直接共享的通道。在调用 setData
之后,会将数据使用 JSON.stringify
进行序列化,再拼接成脚本,然后再传给视图层渲染,这样的话,当数据量非常大的时候,小程序就会变得异常卡顿,性能很差。
Taro 在框架级别帮助开发者进行了优化,在 setData
之前进行了一次数据 Diff,找到数据的最小更新路径,然后再使用此路径来进行更新。例如
// 初始 state
this.state = {
a: [0],
b: {
x: {
y: 1
}
}
}
// 调用 this.setState
this.setState({
a: [1, 2],
b: {
x: {
y: 10
}
}
})
在优化之前,会直接将 this.setState
的数据传给 setData
,即
this.$scope.setData({
a: [1, 2],
b: {
x: {
y: 10
}
}
})
而在优化之后的数据更新则变成了
this.$scope.setData({
'a[0]': 1,
'a[1]': 2,
'b.x.y': 10
})
这样的优化对于小程序来说意义非常重大,可以避免因为数据更新导致的性能问题。
更加丰富的 JSX 语法支持
前面已经提到 Taro 使用 React 语法规范来开发多端应用,这样就必然是采用 JSX 来作为模板,所以 Taro 需要将 JSX 编译成各个端支持的模板,其中以小程序端最为复杂,Taro 需要将 JSX 编译成小程序的 WXML 模板。
在开源的过程中,Taro 支持的 JSX 写法一直在不断完善,力求让开发体验更加接近于 React,主要包括以下语法支持:
- 支持 Ref,提供了更加方便的组件和元素定位方式
- 支持 this.props.children 写法,方便进行自定义组件传入子元素
- 在循环体内执行函数和表达式
- 定义 JSX 作为变量使用
- 支持复杂的 if-else 语句
- 在 JSX 属性中使用复杂表达式
- 在 style 属性中使用对象
- 只有使用到的变量才会作为 state 加入到小程序 data,从而精简小程序数据
目前,除了 Taro 官方 ESLint 插件 eslint-plugin-taro 中限制的语法之外,其他 JSX 语法基本都支持,而在原生组件化的帮助下,未来将会把 ESLint 的限制也逐条取消。
React Native 端转换支持
在 Taro 1.0.0 中,我们将正式推出 React Native 端的转换支持,可以将现有 Taro 项目转换成 RN 版本,但需要注意对样式的处理,因为 RN 支持的样式非常有限,它是属于 CSS 的子集,具体请移步 RN 端转换注意事项。
Taro 的 RN 端基于 Expo 来进行编译构建 RN 程序,开发方式和编译命令与其他端类似,代码目录结构与现有 Taro 项目也基本一致
RN 编译预览模式
# npm script
$ npm run dev:rn
# 仅限全局安装
$ taro build --type rn --watch
# npx用户也可以使用
$ npx taro build --type rn --watch
执行完命令之后,Taro 将会开始编译文件,最终获得 RN 端的编译指引,并且启动你的应用了
React Native 端完整开发流程请移步 React Native 开发流程介绍。
更加健全的 TypeScript 支持
随着前端项目的复杂度和规模的增加,近年来越来越多的项目开始使用 TypeScript 进行开发。Taro 也注意到了这一趋势,在开源之初就提供了对 TypeScript 的支持。在社区的帮助下,Taro 对 TypeScript 的支持也更加健全和完善:
@tarojs/cli
可以直接创建 TypeScript 项目@tarojs/components
包含了所有组件的类型定义@tarojs/taro
的所有 API 也都包含了类型定义@tarojs/redux
和taro-ui
也都全部内置了类型定义- 构建系统的编译器从 Babel 切换到原生 TypeScript 编译器,支持所有 TypeScript 语法
H5 端转换优化
同时,Taro 在 H5 端的转换中,也进行诸多转换优化,修复了之前版本 H5 下诸多 Bug,让 H5 端路由系统更加健壮,同时开放了 Webpack 配置,可以让开发者自由地进行相关配置。
最后,附上 Taro 完整的 迭代历程。
重生之路
正如上文提到,Taro 1.0.0 带来许多新的优秀特性,而同时,在社区内的 Bug 反馈已经愈来愈少,这也是开源期间不断努力打磨的结果。
从 6.7
到行文截止,Taro 一共经历了 1800 余次提交,平均每天近 20 次,最多的一天达 30 次。每一次提交都是进步,每一次提交都让 Taro 更加强大。经过这么多次迭代之后,已经让 Taro 获得重生,尤其是小程序组件化重构完成之后,Taro 从旧版架构的泥潭中一跃而出,成为更加健壮的开发框架。
在我们自己不断反思、优化的同时,也积极融入开源社区,依托社区的力量去建设 Taro。
GitHub ISSUES 是检验一个开源项目靠谱程度的标准之一,到目前为止,一共收到了 500 余个 ISSUES,已关闭近 400 个,关闭率在 80% 左右,未关闭的也大部分是一些功能的迭代需求。在 Taro 开发团队内部更是要求每一个 ISSUE 的响应时间不能超过 24 小时。正是因为这些 ISSUES ,让我们不断意识到 Taro 的不足,让我们知道如何去进行迭代。
同时,我们也一直鼓励社区的开发者积极提 PR,一个优秀的开源项目需要依靠整个社区的力量才能完善起来,到目前为止,一共收到了 120 余个 PR,已几近全部合入,这些 PR 为 Taro 注入了许多新鲜血液,让 Taro 更加健壮,我们也期望能有更多的开发者可以加入进来,一起来让 Taro 更加美好。
在 GitHub 上交流之余,我们也为开发者们开通了官方微信群供大家一起讨论 Taro 与技术,目前已有超过 1700 位开发者在关注、使用 Taro ,期待更多开发者的加入。
开发者生态完善
在开源之初,Taro 一直处于封闭的状态,没有适配的 UI 库,也无法使用第三方组件库,而这些对开发效率的桎梏非常严重,社区内对此反馈较多。
所以,在 1.0.0-beta
版本开发期间,Taro 团队开发了多端 UI 库打包功能,提供了 taro build --ui
命令来将按照一定规则组织的代码打包成可以在 Taro 中使用的多端 UI 库。
并且,基于这一功能,我们推出了首个可以跨多端使用的多端 UI 库 Taro UI,目前已经支持了微信小程序与 H5 端,不久之后将完成 React Native 端的适配,可以同步提供给 React Native 端使用。
目前,多端 UI 库打包功能还处于内测阶段,在 Taro 1.0.0 发布之后,这一功能将同步发布,这样更多开发者就可以为 Taro 开发更丰富的多端组件库和 UI 库了。
未来规划
Taro 将会继续保持迭代,目前已经规划了如下重要功能。
便捷测试
在编译时与运行时提供代码诊断的功能,分析代码优劣,判定代码写法是否规范,以便帮助开发者规避一些由于写法带来的问题。
同时将提供一套测试方案,方便开发者书写并运行组件测试用例,提升代码质量。
多端同步调试
目前 Taro 只能一次调试一个端,这对于开发多端应用来说效率略低,所以,计划提供微信小程序/ H5 / React Native 端同时调试的功能,可以一键启动多端同时编译,从而获得多端同步预览。
微信小程序/H5 代码转 Taro 代码
目前已支持 Taro 代码到小程序代码、 H5 代码的转换,在未来,将提供逆向转换功能,帮助开发者将原本就存在的小程序/H5 项目直接转换成 Taro 项目,从而让原本只能运行在一端的项目获得多端运行的能力,降低开发者的重构成本。
与 React 新特性保持同步
Taro 是遵循 React 语法规范的,但是 React 一直在迭代在变化,Taro 作为 React 的追随者也将会保持与 React 新特性同步,让 Taro 最大程度接近 React 开发体验。
快应用端支持
目前 Taro 已经完成了快应用端组件库与 API 的适配,快应用端的文件转换与模板转换也正在开发中,不久的将来就会发布支持快应用端转换的版本。
支付宝小程序与百度智能小程序支持
已预研支付宝小程序与百度智能小程序转换的可行性,即将进入开发。
多端可视化拖拽搭建
目前 Taro 是依靠开发者手工编写代码来获得多端应用的,Taro 未来计划提供一个多端可视化拖拽搭建的功能,可以通过拖拽组件的方式来生成多端应用。
同时,Taro 将联合各大公司小程序开发团队,推出丰富的行业模板,为各行业应用可视化搭建提供完整的解决方案。
使用案例
在开源期间,随着 Taro 的逐步完善,越来越多的开发者加入到 Taro 的使用、开发中,产生了更多更优秀的使用案例。
特别鸣谢
Taro 的发展离不开广大开源爱好者的帮助,在此特别鸣谢广大 Taro 的使用者以及 Taro 主要贡献者(排名不分先后)。
- aijiacy
- AlexStacker
- AsukaSong
- atzcl
- Boshen
- Bless-L
- beidan
- Chen-jj
- cuitianze
- dogbutcat
- finian
- frontlich
- guotie
- icodytan
- JerrySir
- js-newbee
- jas0ncn
- jinjinjin0731
- kdong007
- kenberkeley
- Lizhooh
- Littly
- lolipop99
- lijinke666
- looch
- ladjzero
- limichange
- leeenx
- luckyadam
- ly525
- Manjiz
- mclockw
- Mr-Prune
- missmimia
- mushan0x0
- Pines-Cheng
- rojer95
- ronffy
- Songkeys
- Simbachen
- smoothdvd
- soulhat
- thewei
- wowlusitong
- xunge0613
- YikaJ
- yuche
- zaaack
- zacksleo
- ZodiacSyndicate
- zuoge85
- zuorichongxian