做者:凹凸曼-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),不定時推送文章。