Skip to main content

Taro 1.3 震撼升级:全面支持 JSX 语法和 HOOKS

· One min read

在 Taro 1.2 发布之后,Taro 在业界收获了巨大的赞誉和关注:GitHub 上 Star 数量超过 19000 粒,NPM 下载量也稳居同类开发框架之首,同时 Taro 团队也和腾讯、百度、华为等数十家业界巨头的研发团队展开了深入和有效的合作。

Taro 1.3 是我们酝酿最久的版本:经历了横跨 6 个月的开发时间,近 2000 次的代码提交,近百位开发者的共同参与。我们终于在今天骄傲地发布了 Taro 1.3。

Taro 1.3 的特性包括但不限于:

  • 支持快应用和 QQ 小程序的开发
  • 全面支持 JSX 语法和 React Hooks
  • 大幅提高 H5 性能和可用性
  • Taro Doctor

支持快应用和 QQ 小程序的开发

快应用的开发模式非常特别,它的 API、组件系统、组件库和其他小程序端差异非常大,并且快应用只是一个标准,各家安卓厂商对运行时的实现也各不相同。而这块「硬骨头」终于也被 Taro 啃下了。

QQ 小程序作为新兴的小程序类容器,大家普遍对它知之甚少,但 Taro 也率先实现了对 QQ 小程序的支持。

支持快应用和 QQ 小程序意味着 Taro 真正对业界主流小程序实现了「全覆盖」,不管你的业务要支持哪一个小程序端,只要维护一套代码,Taro 就能生成对应小程序平台的代码。同时 Taro 也成为了业界首个同时支持微信小程序、百度智能小程序、字节跳动小程序、支付宝小程序、快应用、QQ 小程序共 6 端小程序的开发框架。

taro.jd.com.png

全面支持 JSX 语法和 React Hooks

作为使用 React 和 JSX 语法的开发框架,Taro 早期的版本在编译器和编辑器检查工具都对语法做了高强度的限制。而在 Taro 1.3 中,开发者可以充分发挥自己的创造力和想象力,可以任意地写 if-else,可以任意地写匿名函数,可以把 JSX 放在类函数中,也可以放在普通函数中,等等。只要编译器和和 ESLint 不报错,就可以这么写。

虽然 React Hooks 正式稳定的时间并不长,但我们认为这个特性能有效地简化开发模式,提升开发效率和开发体验。即便 Hooks 的生态和最佳实践还尚未完善,但我们相信未来 Hooks 会成为 React 开发模式的主流,也会深刻地影响其它框架未来的 API 构成。所以我们优先把 React Hooks 带到了 Taro 中,还写了两个小例子展示如何在 Taro 中使用 Hooks:

V2EX: https://github.com/NervJS/taro-v2ex-hooks

TodoMVC: https://github.com/NervJS/taro-todomvc-hooks

carbon.png

全新生命周期和 Context API

在 Taro 1.3 我们还实现了 React 16 的新生命周期函数 static getDerivedStateFromProps()getSnapshotBeforeUpdate()。当新的生命周期函数注入到类组件时,老的生命周期函数将不会被调用,没有使用新的生命周期函数则不会影响原有生命周期的调用。就多数情况而言,我们更推荐使用新的生命周期来构建你的类组件,因为这样能减少一次渲染和更新的开销。更多详细信息可以查看相关文档

Taro 1.3 还实现了 React 16 的 createContextcontextTypeuseContext API。新 Context 通过声明式的 API 来传递组件的更新,使得Taro 跨组件通信和共享状态更为直观。同时,例如 react-redux 这样的热门库也正在基于 ContextHooks 进行重构,我们也非常期待与社区一起探索 React/Taro 新的开发与设计模式。

大幅提高 H5 性能和可用性

作为除微信小程序之外需求量最高的端,我们一直都部署了重要的开发战力在 H5 端。而在 Taro 1.3 中,我们优化了编译代码的方式,实现了资源最小引入和按需引入,将原有最小项目的编译大小降低了 80% 左右。这对于网络状况不佳的 H5 端无疑是巨大的提升。

H5 端的 API 数量和质量也得到了大幅地增长,Taro 1.3 新增了 28 个 H5 API,解决了上百个 H5 相关的 issue。

关于 H5 端性能更感兴趣可以查看文章:《决战性能之巅 - Taro H5 转换与优化升级》

Taro Doctor

我们还从 Flutter Doctor 中得到启发,开发了 Taro Doctor。 Taro Doctor 就像一个医生一样,可以诊断项目的依赖、设置、结构,以及代码的规范是否存在问题,并尝试给出解决方案。

但和真正的医生不一样,Taro Doctor 不需要排队挂号,也不用花钱。你只需要在终端运行命令:taro doctor,就像图里一样:

taro-doctor.png

还有更多

除了以上的特性之外,Taro 1.3 还做了许多额外的工作,这些工作可能对日常开发影响不大,但为 Taro 的稳定性以及将来更多的可能性夯实了基础:

组件传参(props)系统重构

在 Taro 1.0 到 1.2 的小程序端,我们一直使用原生小程序框架的组件传参系统,但小程序组件系统没办法传递函数的值,也无法传递非具名参数,并且各小程序组件的实现各不相同。为了解决这些问题,在 Taro 1.3 中我们自己实现了一套组件传参系统。新系统会使得传参相关的代码更为可靠,同时也是我们支持更多 JSX 语法的基础。

命令行工具(CLI) 重构

在 Taro 1.3,我们将命令行工具使用 TypeScript 进行了重构并逐步添加更多测试用例。重构之后我们可以更加大胆地为 CLI 添加新功能,替换老旧依赖。同时我们也会将 CLI 的功能以 API 的形式暴露出来,赋能给其它开发工具和我们的合作伙伴。

移动端容器更换

我们和京东的 ARES 团队合作,把原有的移动端容器 expo 替换为深度定制的 JDReact。JDReact 大幅提升了 Taro 移动端的可控性,可以让我们突破 expo 的掣肘,引入原生移动端代码,提供定制功能和 API,并且性能和稳定性的表现都会更好。

支持开发小程序插件

小程序插件是小程序带来的一个非常优秀的特性,可以极大地提高代码复用率,降低包大小,为开发者带来诸多便利,目前微信、支付宝小程序已经支持插件功能。而从 1.3 版本开始,Taro 支持直接开发微信与支付宝小程序插件,这意味着 Taro 项目将和小程序插件无缝对接,不再有开发模式切换的成本。

支持「小程序·云开发」

「小程序·云开发」是微信小程序联合腾讯云团队提供的一个非常强大的功能,它是一款 Serverless 服务,为开发者提供了「云函数」、「云数据库」和「云文件存储」三大能力,并且将这些能力封装成特定的接口,可以帮助开发者快速构建微信小程序的后端服务。为了让 Taro 开发者能够享受到「小程序·云开发」的能力,Taro 也加入了对「小程序·云开发」的支持,为「小程序·云开发」提供了初始化模板,并且将小程序云相关的 API 进行了封装,方便开发者进行使用。同时,「小程序·云开发」已提供 H5 版本的 SDK,Taro 支持将小程序、H5 的调用方式进行统一封装,帮助开发者快速打造 Serverless 的多端应用。

升级兼容性

正如前面所提到,Taro 1.3 是一个酝酿时间最久,拥有特性最多的大版本,对 Taro 底层也进行了不小的重构,所以,1.3 版本的升级带了以下 2 个兼容性问题。

JSX 中的事件监听函数必须绑定作用域

在之前的 Taro 版本中,JSX 中绑定的事件监听函数,是可以不需要绑定任何作用域,就能访问到组件实例的,例如

import Taro, { Component, Config } from '@tarojs/taro'
import { View, Button } from '@tarojs/components'

export default class Test extends Component {
state = {
hello: 'noclick'
}
clickHandler () {
this.setState({
hello: 'click'
})
}

render () {
return (
<View className={styles.index}>
<Button onClick={this.clickHandler}>点击</Button>
</View>
)
}
}

上述例子中,<Button /> 按钮绑定的点击事件,在之前版本中是能够正常执行的,Taro 会默认将 clickHandler 的作用域绑定为当前组件实例,但是这并不符合 React 中的实际情况,所以,在 1.3 版本中,我们对这一问题进行了修复,现在 JSX 中的事件监听函数必须绑定作用域,否则就会报错。

上述代码中 JSX 部分可以修改为如下

render () {
return (
<View className={styles.index}>
<Button onClick={this.clickHandler.bind(this)}>点击</Button>
</View>
)
}

或者你也可以在 constructor 中将函数进行提前绑定作用域,

constructor () {
this.clickHandlerBind = this.clickHandler.bind(this)
}

render () {
return (
<View className={styles.index}>
<Button onClick={this.clickHandlerBind}>点击</Button>
</View>
)
}

还有一种做法是,将 clickHandler 写成箭头函数,这种方式在新旧版本中均可以正常运行。

暂时无法在原生应用中使用 Taro 组件

在之前版本中,使用 Taro 编译后的组件是可以直接用在原生项目中的,以提升复用性,但 1.3 版本由于组件的 props 系统彻底重构了,升级 1.3 后暂时无法在原生项目中使用 Taro 组件,我们正在积极处理这个问题,在后续版本中将继续支持这一特性。

在框架之外

Taro 团队除了 1.3 版本中完善多端适配,提高框架开发体验和开发效率之外,我们还在生态建设上付出了诸多努力,其中包括全新升级的官网,物料/插件市场,独立的社区/论坛。

我们认为,Taro 能够安身立命的本钱是作为开发框架的硬实力,但真正决定 Taro 能走多远却是生态、社区以及合作伙伴。 我们在 1.3 已经把实力大幅增强,现在邀请你一起参与或观察 Taro 在生态和社区的建设: