
作者:凹凸曼-JJ
自 7 月初我們正式發布了 Taro 3,至今半年時間已然略去,期間我們不斷地修復著問題,同時也在構想著下一個 minor 版本,
面對小程式平臺越來越多的大環境,Taro 是選擇偏安一隅,只支持部分的主流小程式,還是成為所有小程式平臺開發、多端轉換的基礎設施,我們在 v3.1 給出了答案:開放式架構,
一、開放式架構
背景
近年來業界推出的小程式平臺越來越多,但 Taro 核心維護的平臺只有 6 個(微信、支付寶、百度、頭條、QQ、京東小程式),因此常常有同學提出能不能支持某某平臺的 Feature Request,
基于目前的架構,對于單一平臺的兼容性代碼分布于 Taro 核心庫的各個角落,涉及編譯時與運行時等部分,支持一個新的平臺需要改動所有的這些地方,開發復雜度高,同時社區也難以參與貢獻,
為此我們萌生了打造一個開放式框架的想法,目標是可以通過插件的形式擴展 Taro 的端平臺支持能力:
- 插件開發者無需修改 Taro 核心庫代碼,即可撰寫出一個端平臺插件,
- 插件使用者只需安裝、配置端平臺插件,即可把代碼編譯到指定平臺,
- 開發者可以繼承現有的端平臺插件,然后對平臺的適配邏輯進行自定義,
端平臺插件架構圖

Taro 基于開放式架構的改動
1. 同步了小程式最新特性
我們把內置支持的 6 個平臺封裝成了插件,CLI 默認會全部加載這些插件,封裝的程序中,我們檢索了各小程式最新的組件、API,并全數進行更新與支持,對齊各小程式最新的能力,
2. 新增支持轉換的平臺
借助開放式架構,我們撰寫了若干端平臺插件,開發者安裝后即可使用:
- 企業微信插件:@tarojs/plugin-platform-weapp-qy
- 釘釘小程式插件:@tarojs/plugin-platform-alipay-dd
- 支付寶 IOT 小程式插件:@tarojs/plugin-platform-alipay-iot
- 快手小程式插件(體驗版):@tarojs/plugin-platform-kwai
對開發者的影響
沒有影響,改動屬于 Taro 內部架構重構,不會影響開發者使用,
還可以做什么有意思的事
除了擴展新的編譯平臺,我們還可以通過繼承于現有的端平臺插件,來撰寫自定義的端平臺插件,對平臺的適配邏輯進行自定義:
如何撰寫端平臺插件:檔案地址
1. 快速修復問題
由于小程式平臺眾多,而且它們也在不斷地迭代,往往會出現 Taro 對某個小程式新推出的組件或 API 支持不及時的問題,這時開發者首先需要聯系 Taro 團隊,再等待我們跟進修復、發布新版本后才能正常使用,平均需要等待一周或兩周的時間才能得到解決,
而基于開放式架構,開發者能夠通過繼承某個端平臺插件,迅速開發出自定義端平臺插件,完成對這些新組件或 API 的支持,無需等待 Taro 發布版本,
為微信小程式拓展 API 的例子:
- 運行時注入 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()
}
})
}
2. 屬性精簡
因為小程式組件的屬性和事件都必須靜態寫死,不可以動態添加,所以 Taro 會把組件的所有屬性和事件全部在模板里提前進行系結,
但實際專案中很多情況下并不會使用到組件的所有屬性和事件,回圈這些冗余的屬性和事件系結也會占據很大一部分的體積,另外太多的事件系結也會在一定程度上降低小程式的性能,
以下是 View 組件模板的偽代碼:
<template name="tmpl_0_view">
<view
hover-
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="..."
onTap="..."
id="..."
>
...
</view>
</template>
Taro 需要把 View 組件的所有屬性和事件提前進行系結,才能滿足不同開發者的使用需求,但可能對于某位開發者來說,整個專案的 View 組件都沒有使用到 hover-stop-propagation 這個屬性,那么則可以考慮把它精簡掉,不編譯到 View 組件的模板當中,
需要注意的是,對屬性的精簡可能會引起不必要的問題、使專案的維護變得困難,特別當專案變大,開發者眾多時,需要謹慎設計和使用,
二、重要問題修復
v3.1 除了包括開放式架構的調整外,也不忘鞏固核心,以下是 v3.1 對重要問題的修復情況,有一些在 v3.0 的 patch 版本已經推出,一些則是 v3.1 中才推出,均予以列出:
1. [Breaking Change]修復 Vue 中 App 生命周期被呼叫兩次的問題
注意,此修復含有【Breaking Change】,如果你正在把 Vue 專案從 v3.0 升級到 v3.1,需要對入口組件進行如下修改:
// app.js
// v3.0
// Taro 運行時內部本來就會呼叫一次 new Vue,
// 用戶的入口組件多呼叫一次的話,會導致生命周期函式重復觸發
const App = new Vue({
// ...
})
// v3.1
// 用戶在入口檔案中只需要匯出入口組件的配置物件,不需要再呼叫 new Vue
const App = {
// ...
}
2. 優化反向轉換功能
v3.1 中我們對反向轉換功能(Taro convert)進行了廣泛的驗證,修復了大量問題,現已達到比較高可用的狀態,
詳細檔案:https://taro-docs.jd.com/taro/docs/next/taroize,
主要變動:
- 支持使用
Behavior - 支持使用自定義 tabbar
- 支持配置全域
usingComponents - 修復
catch事件不能阻止冒泡的問題 - 修復不支持掛載額外屬性到 app 物件的問題
- 修復回圈的 key 值沒有被正確編譯的問題
- 修復編譯時沒有處理樣式中參考的字體的問題
反向轉換例子
我們嘗試使用 taro convert 轉換了四個 GitHub 上最熱門的開源微信小程式應用,它們轉換之后都表現良好:
EastWorld/wechat-app-mall - 微信小程式商城
tumobi/nideshop-mini-program - 基于 Node.js + MySQL 開發的開源微信小程式商城
RebeccaHanjw/weapp-wechat-zhihu - 仿知乎
jectychen/wechat-v2ex - V2EX
3. 支持阻止小程式滑動穿透
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>
4. 修復使用了 HOC 后分享生命周期方法不觸發的問題
倘若我們在 v3.0 的 React 框架下,把頁面使用 HOC 進行包裹,如 react-redux 的 @connect,那么我們設定的一些分享生命周期:onShareAppMessage, onShareTimeline 都將不會被觸發,這時需要在頁面的組態檔中對應設定 enableShareAppMessage: true、enableShareTimeline: true 才能解決,
v3.1 會在編譯時掃描 onShareAppMessage、 onShareTimeline 是否有被呼叫,進而自動在頁面組態檔中加上對應配置,大部分場景下不需要用戶手動設定,
注意,如果分享生命周期被封裝在基類或自定義 Hooks 中,還是需要手動加上對應配置,
5. 修復支付寶小程式使用原生自定義組件報錯的問題
在 v3.0,支付寶小程式使用原生自定義組件時,會報“元素不存在”的錯誤,
這是因為支付寶小程式中規定,頁面參考到的自定義組件,需要在頁面對應的 axml 檔案中定義,而 Taro 會把自定義組件定義在全域模板檔案 base.axml 中,
因此 3.1 會識別出使用了原生自定義組件的頁面,把這些頁面的模板都在頁面對應的 axml 里進行定義,
6. 優化 base.xml 模板體積
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 檔案夾洗掉),至此升級結束,
Breaking
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 貢獻過代碼的各位,排名不分先后:
- @wuchangming
- @SyMind
- @zhuxianguo
- @Songkeys
- @vdfor
- @Spencer17x
- @wingsico
- @w91
- @fjc0k
- @Leechael
- @southorange1228
- @alexlees
- @cncolder
- @rottenpen
- @gcxfd
- @twocucao
- @pengtikui
- @kala888
- @LengYXin
- @iugo
- @xuchengzone
- @csolin
- @xiaoyao96
- @zhaoguoweiLLHC
- @baranwang
- @fred8617
- @huanz
- @Cslove
- @002huiguo
- @jazzqi
- @Jetsly
- @yuezk
- @lukezhange001
- @k55k32
- @Soul-Stone
- @hisanshao
- @gjc9620
- @younthu
- @digiaries
- @ZeroTo0ne
- @GoodbyeNJN
歡迎關注凹凸實驗室博客:aotu.io
或者關注凹凸實驗室公眾號(AOTULabs),不定時推送文章:

轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/235027.html
標籤:其他
