做者:凹凸曼-JJhtml
自 7 月初咱们正式发布了 Taro 3,至今半年时间已然略去。期间咱们不断地修复着问题,同时也在构想着下一个 minor 版本。node
面对小程序平台愈来愈多的大环境,Taro 是选择偏安一隅,只支持部分的主流小程序,仍是成为全部小程序平台开发、多端转换的基础设施,咱们在 v3.1 给出了答案:开放式架构。react
近年来业界推出的小程序平台愈来愈多,但 Taro 核心维护的平台只有 6 个(微信、支付宝、百度、头条、QQ、京东小程序),所以经常有同窗提出能不能支持某某平台的 Feature Request。git
基于目前的架构,对于单一平台的兼容性代码分布于 Taro 核心库的各个角落,涉及编译时与运行时等部分。支持一个新的平台须要改动全部的这些地方,开发复杂度高,同时社区也难以参与贡献。github
为此咱们萌生了打造一个开放式框架的想法。目标是能够经过插件的形式扩展 Taro 的端平台支持能力:npm
咱们把内置支持的 6 个平台封装成了插件,CLI 默认会所有加载这些插件。封装的过程当中,咱们检索了各小程序最新的组件、API,并全数进行更新与支持,对齐各小程序最新的能力。json
借助开放式架构,咱们编写了若干端平台插件,开发者安装后便可使用:redux
没有影响,改动属于 Taro 内部架构重构,不会影响开发者使用。小程序
除了扩展新的编译平台,咱们还能够经过继承于现有的端平台插件,来编写自定义的端平台插件,对平台的适配逻辑进行自定义:微信小程序
如何编写端平台插件: 文档地址
因为小程序平台众多,并且它们也在不断地迭代,每每会出现 Taro 对某个小程序新推出的组件或 API 支持不及时的问题。这时开发者首先须要联系 Taro 团队,再等待咱们跟进修复、发布新版本后才能正常使用,平均须要等待一周或两周的时间才能获得解决。
而基于开放式架构,开发者可以经过继承某个端平台插件,迅速开发出自定义端平台插件,完成对这些新组件或 API 的支持,无需等待 Taro 发布版本。
为微信小程序拓展 API 的例子:
/** plugin/apis.ts */ export function initNativeApi (taro) { // 挂载额外 API:Taro.xxx() taro.xxx = function () {} } /** plugin/runtime.ts */ import { mergeReconciler } from '@tarojs/shared' import { initNativeApi } from './apis' // 把 initNativeApi 合并到 reconciler 中。 // 这样能够侵入 Taro 运行时并修改 Taro 对象,达到增长 API 的目的 mergeReconciler({ initNativeApi })
/** plugin/program.ts */ import { Weapp } from '@tarojs/plugin-platform-weapp' // 继承微信小程序 export default class Example extends Weapp { platform = 'example' // 步骤 1 中,runtime 文件的路径 runtimePath = `@tarojs/plugin-platform-example/dist/runtime` } /** plugin/index.ts */ import Example from './program' import type { IPluginContext } from '@tarojs/service' export default (ctx: IPluginContext) => { ctx.registerPlatform({ name: 'example', useConfigName: 'mini', async fn ({ config }) { const program = new Example(ctx, config) program.start() } }) }
由于小程序组件的属性和事件都必须静态写死,不能够动态添加,因此 Taro 会把组件的全部属性和事件所有在模板里提早进行绑定。
但实际项目中不少状况下并不会使用到组件的全部属性和事件,循环这些冗余的属性和事件绑定也会占据很大一部分的体积,另外太多的事件绑定也会在必定程度上下降小程序的性能。
如下是 View 组件模板的伪代码:
<template name="tmpl_0_view"> <view hover-class="..." hover-stop-propagation="..." hover-start-time="..." hover-stay-time="..." animation="..." onTouchStart="..." onTouchMove="..." onTouchEnd="..." onTouchCancel="..." onLongTap="..." onAnimationStart="..." onAnimationIteration="..." onAnimationEnd="..." onTransitionEnd="..." disable-scroll="..." hidden="..." onAppear="..." onDisappear="..." onFirstAppear="..." style="..." class="..." onTap="..." id="..." > ... </view> </template>
Taro 须要把 View
组件的全部属性和事件提早进行绑定,才能知足不一样开发者的使用需求。但可能对于某位开发者来讲,整个项目的 View
组件都没有使用到 hover-stop-propagation
这个属性,那么则能够考虑把它精简掉,不编译到 View
组件的模板当中。
须要注意的是,对属性的精简可能会引发没必要要的问题、使项目的维护变得困难,特别当项目变大,开发者众多时,须要谨慎设计和使用。
v3.1 除了包括开放式架构的调整外,也不忘巩固核心。如下是 v3.1 对重要问题的修复状况,有一些在 v3.0 的 patch 版本已经推出,一些则是 v3.1 中才推出,均予以列出:
注意,此修复含有【Breaking Change】,若是你正在把 Vue 项目从 v3.0 升级到 v3.1,须要对入口组件进行以下修改:
// app.js // v3.0 // Taro 运行时内部原本就会调用一次 new Vue, // 用户的入口组件多调用一次的话,会致使生命周期函数重复触发 const App = new Vue({ // ... }) // v3.1 // 用户在入口文件中只须要导出入口组件的配置对象,不须要再调用 new Vue const App = { // ... }
v3.1 中咱们对反向转换功能(Taro convert
)进行了普遍的验证,修复了大量问题,现已达到比较高可用的状态。
详细文档:https://taro-docs.jd.com/taro/docs/next/taroize。
Behavior
usingComponents
catch
事件不能阻止冒泡的问题咱们尝试使用 taro convert
转换了四个 GitHub 上最热门的开源微信小程序应用,它们转换以后都表现良好:
EastWorld/wechat-app-mall - 微信小程序商城
tumobi/nideshop-mini-program - 基于 Node.js + MySQL 开发的开源微信小程序商城
RebeccaHanjw/weapp-wechat-zhihu - 仿知乎
jectychen/wechat-v2ex - V2EX
v3.0 推出后反馈最多的问题之一,就是在 touchmove
事件回调中调用 e.stopPropagation()
并不能阻止滑动穿透。
这是由于 Taro 3 的事件冒泡机制是单独在小程序逻辑层实现,全部事件都是绑定的 bind
而不是 catch
。所以touchmove
事件回调中调用 e.stopPropagation()
只会阻止上层组件的事件回调触发,而没有 catchtouchmove
能阻止滑动穿透的能力。
v3.1 中咱们为 View
组件增长了 catchMove
属性,只要 catchMove
属性值为 true
,就会使用 catchtouchmove
代替 bindtouchmove
进行事件绑定,从而得到阻止滑动穿透的能力。
用法:
<View class='parent'> <View class='modal' catchMove>滑动 .modal 时,并不会令 .parent 也一块儿滑动</View> </View>
假若咱们在 v3.0 的 React 框架下,把页面使用 HOC 进行包裹,如 react-redux
的 @connect,那么咱们设置的一些分享生命周期:onShareAppMessage
, onShareTimeline
都将不会被触发。这时须要在页面的配置文件中对应设置 enableShareAppMessage: true
、enableShareTimeline: true
才能解决。
v3.1 会在编译时扫描 onShareAppMessage
、 onShareTimeline
是否有被调用,进而自动在页面配置文件中加上对应配置,大部分场景下不须要用户手动设置。
注意,若是分享生命周期被封装在基类或自定义 Hooks 中,仍是须要手动加上对应配置。
在 v3.0,支付宝小程序使用原生自定义组件时,会报“元素不存在”的错误。
这是由于支付宝小程序中规定,页面引用到的自定义组件,须要在页面对应的 axml 文件中定义。而 Taro 会把自定义组件定义在全局模板文件 base.axml 中。
所以 3.1 会识别出使用了原生自定义组件的页面,把这些页面的模板都在页面对应的 axml 里进行定义。
v3.0 刚推出,不少同窗反馈小程序体积过大的问题,其中一个缘由是编译产物中 base.xml
这个模板的体积太大了。
自 v3.0.9 后,咱们对模板生成逻辑进行了重构:可能嵌套引用自身的组件,模板默认生成 16 次,如 View
。不会嵌套引用自身的组件,模板只会生成一次,如 Map
。
以微信小程序为例,在最极端的状况下体积优化率达 85% 以上:
从 v2.x 升级的同窗须要先按 迁移指南 进行操做。
从 v3.x 升级的同窗,首先须要安装 v3.1 的 CLI 工具:
npm i -g @tarojs/cli@next
而后进入项目,把 package.json
文件中 taro 相关依赖的版本修改成 3.1.0-beta.4
,再从新安装依赖(建议先把 node_modules 文件夹删除)。至此升级结束。
v3.1 带来了一个 Breaking Change,使用 Vue 进行开发的同窗须要按指示进行修改。
Taro 3 即将支持 React Native,欢迎体验:《增长 React Native 支持的 Taro 3.2.0 版本测试通告》
开源不易,贵在坚持。Taro 团队衷心感谢各位参与过本项目开源建设的朋友,不管是为 Taro 提交过代码、建设周边生态,仍是反馈过问题,甚至只是茶余饭后讨论、吐槽 Taro 的各位。
现诚挚邀请您与 Taro 官方团队交流您的使用状况,有你相伴,Taro更加精彩!问卷地址
最后,特别感谢为 Taro 从 v3.0 走到 v3.1 贡献过代码的各位,排名不分前后:
欢迎关注凹凸实验室博客:aotu.io
或者关注凹凸实验室公众号(AOTULabs),不定时推送文章。