Taro 正式發佈 3.6 版本:支持跨端路由、請求庫,新增鴻蒙、Web 端平臺插件,小程序持續集成 CI 能力升級

兩個月前,我們發佈了 Taro v3.6 的 canary 版本,在技術委員會和社區範圍內提供跨端路由庫、跨框架組件等主要能力和重要修復的測試,併發起社區投票正式確定了當前版本的代號 —— Reach。

Reach

日前 Taro v3.6 正式版本已經發布,下文將圍繞 3.6 版本內的跨端、平臺能力支持等多個方面展開,快速瞭解在 v3.6 中各個重要特性。

一、跨端能力支持

支持各類跨端能力,抹平多端研發之間的體驗差異,是 Taro 一直以來嘗試去實現的,基於 Taro 3 適配多端前端 UI 框架的邏輯,通過在小程序端模擬實現框架所需的 BOM / DOM API 就能達成對於各類跨端能力的適配。

1. 支持路由庫

在 Web BOM 中,History & Location 對象是重要組成部分,它們是實現前端路由的關鍵。Taro 爲支持前端路由庫的使用,在運行時中引入了 histroy location 對象的實現,同時儘可能與 Web 端規範對齊。通過在 window 對象上訪問到 historylocation 對象,並支持監聽 hashchangepopstate 事件,爲跨端使用路由庫提供基礎。

// 統稱: 頁面路由狀態
window.history
window.location

// 支持監聽事件
window.addEventListener('hashchange', () => {})
window.addEventListener('popstate', () => {})

小程序天然支持多頁面(pages 數組配置),因此 Taro 並非以整個應用爲一個路由系統,而是順應小程序規範以頁面維度進行路由管理。每當切換頁面時,會將當前頁面的頁面路由狀態緩存。跳轉至新頁面後會重新創建頁面路由狀態,並掛載在 window 對象上。當返回上一級頁面時,會將上一級頁面的頁面路由狀態重新掛載到 window 對象中。

至此,可以在小程序中使用成熟的前端路由庫了,包括 react-routervue-router。在路由庫中,諸如 <Link> 組件內部會動態生成 <a> 標籤,因此需要引入 `@tarojs/plugin-html`[1] 插件以支持在 Taro 中使用 html 標籤開發組件。

{
  "plugins": ["@tarojs/plugin-html"]
}

在 Taro 編譯過程中,當 DOM 序列化數據的 nn 字段爲 HTML 標籤時,標籤會映射爲對應的小程序組件名稱。由於無法提前預知動態標籤,因此需要應用顯式告知可能會使用到的動態標籤。例如在應用中塞入一個無樣式的標籤名即可:

<View>
  <a></a>
</View>

更多細節可以查看 官方文檔[2],也可以查看官方提供的 DEMO 獲知更多用法。

2. 支持網絡請求庫

與適配各路由庫類似,通過對運行時補充就能支持絕大多數的網絡請求庫,所有請求庫在底層都是通過使用 XMLHttpRequest[3]Fetch[4] 提供能力支持的,而請求庫大多都兼容 XMLHttpRequest 對象,也即是在提供 XMLHttpRequest 對象實現的基礎上,就能支持絕大多數的第三方庫。

支持這些成熟的網絡請求庫(例如 axios[5] 等)就能爲開發者在跨端研發場景下,提供更好的研發體驗。通過引入 @tarojs/plugin-http 插件,爲小程序環境提供網絡請求庫所需的運行時環境支持。

{
  "plugins": ["@tarojs/plugin-http"]
}

注意:當前 @tarojs/runtime 在小程序環境中缺少BlobFormDataFile對象,這在網絡請求庫的文件上傳特性中是必須的,故暫不支持。

在支持網絡請求庫的同時,考慮到部分用戶,特別是 web 轉小程序的項目中依賴 cookie 實現鑑權,@tarojs/plugin-http 插件模擬實現了 document.cookie api 以及通過 http 響應頭 Set-Cookie 來設置客戶端 cookie 值 ,行爲和 web 中保持一致。此功能默認設置爲關閉,需要的可通過 enableCookie 配置開啓。

參數名 類型 默認值 說明
enableCookie Boolean false 支持 document.cookie 、 通過後端返回 Set-Cookie 響應頭來設置 cookie
disabledFormData Boolean true 是否禁用 FormData 全局對象
disabledBlob Boolean true 是否禁用 Blob 全局對象

在 @tarojs/plugin-http 插件中,以 axios 作爲基準庫完成測試,如果在使用其他請求庫時遇到適配問題,可在社區或通過 issues[6] 反饋相關信息。

二、平臺能力支持

拓展更多端平臺,適配支持各端能力與特性,是跨端解決方案不斷髮展的重要組成部分之一。

1. 支持鴻蒙端平臺插件

在 Taro 與 OpenHarmony 建立官方合作關係,並受邀成立 CrossPlatformUI Sig[7](跨平臺前端框架興趣小組)後,讓 Taro 支持支配鴻蒙就一直在議程上,鴻蒙的方舟開發框架提供類 Web 範式編程,支持使用 JS 開發 UI 層,其語法與小程序相接近,可以沿用 Taro 現有的架構適配鴻蒙。

taro-harmony

持續關注 Taro 的開發者可能還記得,在 v3.5-canary 版本時,我們曾推出支持 Taro 應用適配到鴻蒙平臺的插件,但最終沒有合入 v3.5 版本主幹並順勢推出該能力。

@tarojs/plugin-platform-harmony 端平臺插件經過一段時間的打磨,相關能力與特性也在社區推進下持續優化,框架編譯的項目在鴻蒙開發板上得到進一步驗證,同時在 Taro v3.5 新增的 @tarojs/webpack5-runner 編譯內核也能夠爲鴻蒙項目編譯提供支持,終於我們在 v3.6 中再次爲社區開發者提供了適配鴻蒙的端平臺插件。

// config/index.js

config = {
  // 配置使用插件
  plugins: ['@tarojs/plugin-platform-harmony'],
  // harmony 相關配置
  harmony: {
    // 【必填】鴻蒙應用的絕對路徑
    projectPath: path.resolve(process.cwd(), '../MyApplication'),
    // 【可選】HAP 的名稱,默認爲 'entry'
    hapName: 'entry',
    // 【可選】JS FA 的名稱,默認爲 'default'
    jsFAName: 'default'
  }
}

具體使用方法可查看官方文檔[8],需要注意鴻蒙插件不在 Taro 項目內維護,所以並不會每次發佈同版本號版本,直接使用 minor 與 Taro 版本號相同的版本即可。

特別感謝以下同學爲鴻蒙適配作出的貢獻:

@AdvancedCat[9]@jiaozitang[10]@huozhongyi123[11]@troy-sxj[12]@JSZabc[13]@crazyonebyone[14]@evernoteHW[15]@soulhat[16]@xueshuai[17]@LuMeiling[18]

2. React Native 能力

爲了讓整體開發體驗跟 RN 更加一致,減少開發者的理解成本。我們對 @tarojs/rn-runner 的代碼進行了重構。將 Taro RN 需要的所有編譯邏輯,都封裝到了 metro 配置中,與 RN 項目集成會更加靈活。

新版本在項目根目錄下會創建入口文件 index.js 和配置文件 metro.config.js。如項目本身有這兩個文件,則不會生成,需要參考模板[19]進行添加或合併。另外 Taro RN 的相關配置,集中在 resolver 和 transformer 中,可根據相關源碼自行覆蓋調整。

React Native 0.70 版本已於 2022-9-5 正式發佈[20],在 0.70 版本中 Hermes 已成爲默認的 JS 引擎,

v3.6 版本將與 RN 默認配置保持一致,如不需要可自行關閉。Hermes 也帶來了 RN 性能的較大提升,特別是啓動場景,詳細內容參考官方文章[21]

Hermes

Taro 將與 RN 社區保持同步,將默認的 RN 版本設置爲 0.70。相關依賴也已同步至最新版本,仍然可使用 yarn upgradePeerdeps 進行更新。@react-native-community/clipboard@react-native-community/cameraroll 已被棄用,舊版本升級後需要刪除。

注意:升級後將不再支持 iOS 12,詳細內容請參考 discussions[22]。同時 Taro Playground[23] 作爲 RN 端的調試工具及跨端 Demo 同步更新至 v3.6。

3. Web 端能力

通過在社區中收集的相關問題反饋,Taro Web 各類特性也一直在不斷推進,讓開發者在多端研發的體驗能夠儘可能達成一致。面對各類自定義 Web 端能力的需求,雖然有很多方案可以提供組件、API 等能力的補充,但類似小程序端平臺插件這樣的能力在 Web 端中並沒有得到支持。

在 3.6 版本中,我們將 Web 端各類定製化的能力從 runner 中轉移到 @tarojs/plugin-platform-h5 插件中提供,譬如通過配置 useHtmlComponents 模式替換使用的組件庫;註冊 Web Components 組件庫,配置各前端 UI 框架組件適配器;移除不必要的 API 等等特性。

class H5 extends TaroPlatformWeb {
// ...
}

export default (ctx) => {
ctx.registerPlatform({
name: 'h5',
useConfigName: 'h5',
async fn({ config }) {
const program = new H5(ctx, config)
await program.start()
},
})
}

和小程序端一樣,藉助於插件或 TaroPlatformWeb 基類,開發者可以很容易橫向或縱向拓展 Web 端的各項能力,詳情可參考文檔[24]

Web 端也一直在補充各類開發者常用的組件與 API 抹平與小程序端的差異。在 v3.6 版本中新增生命週期、WXML 相關的 API 支持若干,例如:createIntersectionObservercreateMediaQueryObserver 等,同時新增 movable-areamovable-view 等組件支持。

在社區開發者交流時,我們也發現了部分研發場景下需要監聽各 API、組件不支持事件,相比於支持 canIUse 方法在跨端轉換場景中能夠更有效定位問題,所以通過支持 __taroNotSupport 事件滿足相關需求,可以參考以下示例使用。

interface IOption {
name: string // 不支持的組件或 API 名稱
type: 'method' | 'component' // 'method': API; 'component': 組件
category: 'permanently' | 'temporarily' | 'weixin_corp' // 'weixin_corp': 僅在微信公衆號 JS-SDK 環境下支持
args?: any[] // API 傳入參數
instance?: unknown // 組件實例
}
Taro.eventCenter.on('__taroNotSupport', (option: IOption) => {
console.warn('調用不支持的 API 或組件', option)
})

三、跨框架組件庫

藉助於 stencil,Taro 3 得以通過 Web Components 實現一套跨框架組件庫,通過適配器將 Taro 的組件庫提供給各個前端 UI 框架使用,開發者也可以基於這些封裝上層組件,提供更多有趣的能力。

1. Web 端適配器

出於降低開發者維護門檻,與 stencil 組件庫打包流程更好兼容等多方面考慮,在 3.6 版本中我們在升級 stencil 依賴版本的同時,通過官方提供的  ds-output-target[25] 工具替換了原有的自定義適配器。

該版本適配器更好的抹平各個框架組件使用差異,補齊過往版本迭代過程中部分特性兼容性的缺失問題,爲開發者提供更好的體驗。在 3.6 中依舊保留過往版本各框架適配器,可以參考以下示例通過配置別名替換組件庫適配器(不建議使用,後續不會維護舊版適配器,可能無法得到新的組件或特性支持)。

// config/index.js

const config = {
  h5: {
    webpackChain(chain) {
      chain.resolve.alias.set(
        // 當前版本適配層地址 @tarojs/components/dist/[framework]
        '@tarojs/components/dist/react',
        // 舊版本適配層地址 @tarojs/components/dist/[framework]/component-lib
        '@tarojs/components/dist/react/component-lib'
      )
    },
  },
}

2. 虛擬列表

作爲從 Taro 3 開始支持的上層組件,虛擬列表應當是很多開發者都熟悉的特性,在過往版本中也有過數次升級,支持包括 unlimitedSize、relative 定位模式等特性,在 v3.6 版本中我們再次對虛擬列表做出了調整,將其從 @tarojs/components 包中抽離到 @tarojs/components-advanced 中維護(開發者依舊可以通過 @tarojs/components/virtual-list 引用虛擬列表組件),也歡迎大家一同參與上層組件庫的維護與共建,沉澱更多跨端可用的能力。

https://img20.360buyimg.com/ling/jfs/t1/125645/6/13305/50138/5f6aaaa4E2f20eba7/d70a2d2da2d68de1.jpg

在新版本中,虛擬列表支持在選擇 preact、vue3 框架構建的項目中使用,同時在使用各個前端 UI 框架的項目中都支持使用選擇 absoluterelative 不同定位方式,unlimitedSize 模式與傳入 itemSize 函數等特性也得到支持。

以 Vue 爲例,我們需要在入口文件聲明使用:

// app.js 入口文件
import Vue from 'vue'
import registerVirtualList from '@tarojs/components/virtual-list'
// Note: 使用以下路徑導出插件可以在 vue 中獲得更好的類型支持
// import registerVirtualList from '@tarojs/components-advanced/dist/components/virtual-list/vue'

Vue.use(registerVirtualList)

一個最簡單的長列表組件會像這樣,virtual-list  的 5 個屬性都是必填項:

<! –– row.vue 單項組件 ––>
<template>
<view :id="id" :class="index % 2 ? 'ListItemOdd' : 'ListItemEven'"> Row {{ index }} : {{ data[index] }} </view>
</template>

<script>
export default {
props: ['id', 'index', 'data'],
}
</script>

<! –– page.vue 頁面組件 ––>
<template>
<virtual-list
wclass="List"
:height="500"
:item-data="list"
:item-count="list.length"
:item-size="100"
:item="Row"
width="100%"
>
<! –– Vue 中支持列表首尾使用的插槽,對應 React 中的 renderTop、renderBottom 參數 ––>
<template v-slot:top>
<view>top</view>
</template>
<template v-slot:bottom>
<view>bottom</view>
</template>
</virtual-list>
</template>

<script>
import { markRaw } from 'vue'
import Row from './row.vue'

function buildData(offset = 0) {
return Array(100)
.fill(0)
.map((_, i) => i + offset)
}

export default {
data() {
return {
Row: markRaw(Row),
list: buildData(0),
}
},
}
</script>

需要注意的是,爲抹平多框架參數差異便於維護,舊版本中部分命名會統一修改,比如在 React 版本中通過 children 傳入的子節點組件改爲 item;Vue 中的 wclass、wstyle 這類寫法也不再支持。

在新版本中,根據需求和研發場景合理設置 itemSizeoverscanCountplaceholderCount 等參數優化長列表,可以獲得比舊版本更加順滑的體驗,更多詳情可以參考官方文檔[26]

四、研發生態

1. 小程序持續集成 CI

去年 Taro 提供小程序持續集成插件 @tarojs/plugin-mini-ci ,幫助開發者提供更好的研發體驗,經過一年的項目沉澱和反饋,在本次版本重構了去年的所有代碼,並提供了更優秀體驗和靈活的配置。

  • 本次新增特性支持獨立的 openpreviewupload 命令,操作自定義目錄適用於將 taro 作爲項目一部分(混合開發)的開發場景;
  • 同步更新各個小程序端的 CI API 變更(阿里系、抖音小程序變化最大)
  • 新增釘釘小程序 CI 集成;
  • 新增京東小程序 CI 集成;
  • 統一所有平臺 CI 構建後的輸出數據,並將數據傳遞給新增的 onPreviewCompleteonUploadComplete兩個鉤子用戶可以編寫新的插件,基於這個鉤子實現 飛書、釘釘 的 CI 推送功能等等。

以下爲當前各平臺支持的功能情況表:

平臺/功能 自動打開 IDE 輸出預覽二維碼 輸出體驗二維碼
weapp
qywx
alipay
dd
swan
jd

ps:該插件在 taro3.6.0 版本以下亦可支持單獨使用,插件版本號無需保持與其他包同步。

更多詳情可以參考官方文檔[27],同時要特別感謝 @bigMeow[28] 爲 CI 自動化腳本做出的貢獻~

2. PostCSS 版本升級

在 Taro 項目持續迭代的過程中,部分依賴穩定沒有實時跟進各個社區內的特性與優化,並升級相關依賴,PostCSS 就是其中之一。如果開發者想要通過新版本的特性來優化構建流程與最終產物,相對會很困難且可能會存在一定問題阻塞。

爲此在 3.6 canary 通過梳理項目內相關插件與依賴,對 PostcCSS 版本進行梳理並升級,升級後版本爲 v8.4.18。本次升級主要包含以下內容:

  1. 對 Taro 內部的 PostCSS 插件使用 PostCSS 8 版本 API 進行改寫,降低代碼量同時減少插件對 CSS 掃描次數進而提高構建速度;
  2. 使用 peerDependencies 管理 postCSS 依賴,降低用戶的 node_modules 體積和複雜度;
  3. 對 Taro 全量模板的 PostCSS 版本同步進行更新,方便開發者對新特性的使用。

特別感謝 @xueshuai[29] 爲相關工作做出的貢獻,希望開發者可以因此獲得更好的研發體驗。

3. 類型與文檔自動同步

快速同步各平臺支持的類型,一直以來都是十分頭疼的問題之一,想要實時跟進各個平臺以提升用戶體驗十分困難,更多時候我們都通過開發者提交的 PR 或 issue 對這些平臺的類型更新維護。如果能夠根據各個小程序平臺官方提供的文檔自動化生成類型,這對於框架維護和開發者來說會是一個很棒的體驗。

CanIUse

通過在 Taro 社區中的積極探討[30]和論證,我們引入了自動同步各小程序平臺組件類型的腳本機制,並通過與 GitHub CI 讓機器人爲 Taro 倉庫提交類型更新 PR。組件類型的自動化同時讓 Taro 的文檔在類型更新時,同步這些平臺組件的變更,爲開發者提供更好的文檔索引能力。同時我們也在文檔提供了 canIUse[31] 頁面,供開發者快速檢索組件、特性在各個平臺支持的程度。

希望後續也能夠通過和各平臺合作的方式優化該能力,爲開發者提供更好的體驗。在這裏特別感謝 @rebinv8[32] 爲組件類型自動化腳本做出的貢獻~

4. Taro Playground 同步升級

作爲 RN 端的調試工具及跨端 Demo,Taro Playground[33] 同步更新 v3.6 更新。此次更新無法保證向下兼容,使用舊版本 Taro 的開發者,如需調試 Android,可在 releases[34] 中下載舊包進行調試。在 App Store 中,我們只上架最新版本,需要舊版本的開發者請不要開啓應用自動更新。如不慎升級,需自行打包編譯,或聯繫我們加入測試組。

五、升級指南

1. 創建 v3.6 版本項目:

# 安裝 v3.6.0 的 CLI 工具
npm i -g @tarojs/cli@latest
# 創建項目
taro init taro_project

# 也可以跳過安裝 CLI 工具使用 npx 創建項目
npx @tarojs/cli@latest init taro_project

2. 已有項目升級到最新版本:

  1. 將 package.json 文件中 Taro 相關依賴修改爲 3.6.0 版本;
  2. Taro v3.6 將 web 端插件化,需要新增依賴 @tarojs/plugin-platform-h5,同時 @tarojs/router@tarojs/taro-h5 不再需要額外聲明依賴,可自行移除;
  3. 重新安裝依賴,如果安裝失敗或打開項目失敗,可以刪除 node_modulesyarn.lockpackage-lock.json 後重新安裝依賴重新嘗試。

最後

自 Taro 引入技術委員會[35]等機制後,與社區互動愈加頻繁,Taro 也得益於諸多貢獻者[36]的幫助有能力去實現更多有意思的特性,給開發者帶來更好的用戶體驗,這也是 Taro v3.6 在代號「Reach」中的期待。感謝各位參與到 Taro 開源生態共建的同學們,所有的努力都讓 Taro 的生態更加美好,爲建立更加完善、更加可持續的 Taro 開源生態,貢獻力量!

參考資料

[1]

@tarojs/plugin-html: https://nervjs.github.io/taro-docs/docs/use-h5

[2]

官方文檔: https://nervjs.github.io/taro-docs/docs/router-extend

[3]

XMLHttpRequest: https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest

[4]

Fetch: https://developer.mozilla.org/zh-CN/docs/Web/API/Fetch_API

[5]

axios: https://axios-http.com/

[6]

issues: https://github.com/NervJS/taro/issues

[7]

CrossPlatformUI Sig: https://gitee.com/openharmony-sig/taro

[8]

官方文檔: https://nervjs.github.io/taro-docs/docs/harmony

[9]

@AdvancedCat: https://github.com/AdvancedCat

[10]

@jiaozitang: https://github.com/jiaozitang

[11]

@huozhongyi123: https://github.com/huozhongyi123

[12]

@troy-sxj: https://github.com/troy-sxj

[13]

@JSZabc: https://github.com/JSZabc

[14]

@crazyonebyone: https://github.com/crazyonebyone

[15]

@evernoteHW: https://github.com/evernoteHW

[16]

@soulhat: https://github.com/soulhat

[17]

@xueshuai: https://github.com/xueshuai

[18]

@LuMeiling: https://github.com/LuMeiling

[19]

模板: https://github.com/NervJS/taro-project-templates/tree/v3.6/react-native

[20]

React Native 0.70 版本已於 2022-9-5 正式發佈: https://reactnative.dev/blog/2022/09/05/version-070

[21]

官方文章: https://reactnative.dev/blog/2022/07/08/hermes-as-the-default

[22]

discussions: https://github.com/NervJS/taro/discussions/12468

[23]

Taro Playground: https://github.com/wuba/taro-playground

[24]

參考文檔: https://nervjs.github.io/taro-docs/docs/next/platform-plugin/how#web-%E7%AB%AF%E5%B9%B3%E5%8F%B0%E6%8F%92%E4%BB%B6

[25]

ds-output-target: https://github.com/ionic-team/stencil-ds-plugins/blob/master/README.md

[26]

官方文檔: https://nervjs.github.io/taro-docs/docs/next/virtual-list#vue

[27]

官方文檔: https://nervjs.github.io/taro-docs/docs/plugin-mini-ci

[28]

@bigMeow: https://github.com/bigmeow

[29]

@xueshuai: https://github.com/xueshuai

[30]

探討: https://github.com/NervJS/taro/discussions/11740

[31]

canIUse: https://nervjs.github.io/taro-docs/canIUse/

[32]

@rebinv8: https://github.com/robinv8

[33]

Taro Playground: https://github.com/wuba/taro-playground

[34]

releases: https://github.com/wuba/taro-playground/releases

[35]

技術委員會: https://nervjs.github.io/taro-docs/docs/team/#%E6%8A%80%E6%9C%AF%E5%A7%94%E5%91%98%E4%BC%9A

[36]

貢獻者: https://nervjs.github.io/taro-docs/docs/team/role-committer


本文分享自微信公衆號 - 凹凸實驗室(AOTULabs)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章