Taro轉(zhuǎn)React-Native的實(shí)踐總結(jié)和分析思考

本文始發(fā)于我的博文Taro轉(zhuǎn)React-Native的實(shí)踐總結(jié)和分析思考,現(xiàn)轉(zhuǎn)發(fā)至此。

一、前言

Taro 是一套遵循 React 語(yǔ)法規(guī)范的 多端開(kāi)發(fā) 解決方案。

使用 Taro,我們可以只書(shū)寫一套代碼,再通過(guò) Taro 的編譯工具,將源代碼分別編譯出可以在不同端(微信/百度/支付寶/字節(jié)跳動(dòng)/QQ/京東小程序、快應(yīng)用、H5、React-Native 等)運(yùn)行的代碼。

*摘自Taro 介紹

Taro是一套優(yōu)秀的多端開(kāi)發(fā)解決方案。我們團(tuán)隊(duì)自較早期時(shí)(18年底)便開(kāi)始了深入研究,并投入到豐富的微信小程序開(kāi)發(fā)實(shí)踐中,同時(shí)作者還負(fù)責(zé)團(tuán)隊(duì)Taro轉(zhuǎn)百度/字節(jié)跳動(dòng)/React-Native的項(xiàng)目。

本文將介紹Taro轉(zhuǎn)React-Native的項(xiàng)目框架、Taro轉(zhuǎn)React-Native過(guò)程中遇到的問(wèn)題和解決方案、RN的熱更新,以及框架相關(guān)的思考。

項(xiàng)目完成于去年(2019年),最近才抽空重新修改了總結(jié)文檔放到博客上。因此可能有些轉(zhuǎn)換細(xì)節(jié)不是最新的,請(qǐng)留意。

二、項(xiàng)目實(shí)踐

Taro 轉(zhuǎn) React-Native(以下簡(jiǎn)稱RN) 項(xiàng)目,目前應(yīng)用于將“美梨工坊桌面”項(xiàng)目(Taro)轉(zhuǎn)換成美梨桌面 iOS App(基于 RN 進(jìn)行封裝的 App 殼),是 App 的 RN 內(nèi)置包系統(tǒng),主要功能為 RN 所有功能的展現(xiàn),包括協(xié)作項(xiàng)目開(kāi)發(fā)、頁(yè)面展示、公共 Bundle、熱更新、預(yù)下載、一鍵部署等特性。

作用:讓客戶端/前端團(tuán)隊(duì)能支持更靈活的開(kāi)發(fā)協(xié)作、節(jié)省開(kāi)發(fā)成本、支持及時(shí)處理線上問(wèn)題。

2.1 整體框架

包含以下四個(gè)方面。

開(kāi)發(fā)鏈路

  • 基于 NPM 的 Web 開(kāi)發(fā)體驗(yàn)
  • 基于 Webpack 構(gòu)建,完整的項(xiàng)目管理
  • React-Native 二次組件、工具集合類

打包鏈路

  • 自動(dòng)打包、隨版本生成配置
  • 持續(xù)集成、部署、交付

發(fā)布鏈路

  • git webhook,自動(dòng)發(fā)布
  • 后臺(tái) API,OSS 自動(dòng)上傳
  • 發(fā)布配置后臺(tái),通知提醒

Native 支持

  • 推送功能支持
  • 原生路由至 RN 頁(yè)面支持
  • Bundle 文件和資源文件的更新

2.2 RN 準(zhǔn)備工作

目前只在 iOS 平臺(tái)上做部署,所以只展開(kāi) iOS 端的準(zhǔn)備工作。

  • 安裝依賴庫(kù)
brew install node
brew install watchman
  • 安裝 React-Native 命令行工具
npm install -g yarn react-native-cli
  • 安裝 Xcode
  • 在 config/index.js 文件中配置:
rn: {
  appJson: {
    name: 'MeiliDesktop',
  },
}

相關(guān)開(kāi)發(fā)鏈接:

2.3 遇到的問(wèn)題

主要列舉 Taro 轉(zhuǎn)換 React-Native 過(guò)程中遇到的問(wèn)題及處理方法。

2.3.1 環(huán)境/依賴庫(kù)相關(guān)問(wèn)題

  • node-sass

執(zhí)行項(xiàng)目 yarn,安裝 node-sass 庫(kù)會(huì)失敗,根據(jù) node-sass 官網(wǎng)文檔,切換源并使用 npm 可以成功:

npm install -g mirror-config-china --registry=http://registry.npm.taobao.org
npm install node-sass
  • fbjs

提示找不到 fbjs,添加該庫(kù)并執(zhí)行安裝。

  • NervJS/taro-native-shell 殼子應(yīng)用編譯失敗

文檔建議使用 NervJS/taro-native-shell 工程,該工程是 RN 工程中原生的部分。

可能會(huì)遇到環(huán)境或 Xcode 版本兼容問(wèn)題,可以自行生成殼子工程。

react-native init AwesomeProject
  • The UMNativeModulesProxy native module is not exported through NativeModules

使用自行生成的殼子工程需要自行安裝依賴react-native-unimodules,添加到package.jsondependencies中。

  • selector hasGrantedPermission

react-native-unimodules使用的是 0.7.0 版本,發(fā)現(xiàn)換成 0.6.0 即可解決。

"react-native-unimodules": "0.6.0"

2.3.2 組件/樣式問(wèn)題

  • Invariant Violation: Text strings must be rendered within a component.

文字需要包在 Text 組件里面

<View className='page-order-detail__content'>
    {steps && steps.length && (<View></View>)
</View>

上面的代碼也會(huì)提示錯(cuò)誤,需要改成:

<View className='page-order-detail__content'>
    {steps && steps.length > 0 && (<View></View>)
</View>
  • Input 設(shè)置line-height會(huì)導(dǎo)致輸入內(nèi)容顯示異常

內(nèi)容會(huì)顯示偏下并被遮擋

  • Text 組件不支持設(shè)置圓角等
  • Input 不支持設(shè)置Height
  • 400,700,normal 或 bold 之外的 font-weight 值在Android上的React-Native中沒(méi)有效果
  • 不支持100vh設(shè)置
  • 其他不支持的樣式

React-Native的樣式基于開(kāi)源的跨平臺(tái)布局引擎 Yoga ,樣式基本上是實(shí)現(xiàn)了 CSS 的一個(gè)子集,所以會(huì)有些樣式不支持,在出錯(cuò)時(shí)會(huì)給出支持的樣式列表。如 RN 不支持針對(duì)某一邊設(shè)置 style,即 border-bottom-style 會(huì)報(bào)錯(cuò)。

  • 必須使用 Flex 布局
  • 文字要包在 Text 組件里面,否則不顯示
  • position:fixed React-Native 不支持
  • 樣式選擇器僅支持類選擇器,且不支持 組合器
  • RN 中 View 標(biāo)簽?zāi)J(rèn)主軸方向是 column

如果需要兼容各端,最好在布局中顯式聲明主軸方向。

2.3.3 其他問(wèn)題

  • 不支持同步的 Storage 存取

即不支持Taro.setStorageSyncTaro.getStorageSync兩個(gè)同步方法,因此需要對(duì)已有代碼進(jìn)行重構(gòu),使用async/awaitPromise進(jìn)行處理。

  • 找不到方法/函數(shù)

所有的方法參數(shù)傳遞,需要bind(this)

  • this.setState is not a function

尋找未添加bind(this)的方法參數(shù)傳遞,添加bind(this)

  • componentWillMount()即將廢棄

使用componentDidMount()實(shí)現(xiàn)

  • 沒(méi)有讀取文件并進(jìn)行 base64 編碼

使用rn-fetch-blob庫(kù)解決。

2.3.4 其他參考

Taro 官方提供了各端開(kāi)發(fā)前注意事項(xiàng),特別是使用 RN 的樣式區(qū)別。

Taro 官方提供了最佳實(shí)踐,可以參考。

Taro 官方提供了更多資源,可以查看其他團(tuán)隊(duì)的文章分享和遇到的問(wèn)題解決。

2.4 熱更新方案

目前業(yè)界 RN 熱更新方案同樣分為 全量更新 和 增量更新。原理同 Weex 類似,此處不再贅述。

全量更新分為兩部分,即Bundle文件和資源的更新。

  • 目前方案

當(dāng)前項(xiàng)目頁(yè)面較少,整個(gè) Bundle 文件不到 2MB,目前使用全量更新。

資源文件夾先壓縮再上傳;App端下載后進(jìn)行md5驗(yàn)證,驗(yàn)證通過(guò)則解壓到緩存目錄。

在下次重新打開(kāi) App 才讀取緩存的Bundle和 資源。

接口格式可參考以下方案:

{
    "error_code": 0,
    "error_message": "成功",
    "data": {
        "bundle": {
            "version": "190108174500",
            "url": "https://xxx/main.jsbundle",
            "md5": "xxx"
        },
        "assets": {
            "version": "190108174500",
            "url": "https://xxx/assets.zip",
            "md5": "xxx"
        }
    }
}

因?yàn)樵擁?xiàng)目的用戶是公司內(nèi)部員工,目前第一版,所以沒(méi)有對(duì)復(fù)雜情況進(jìn)行處理,后續(xù)應(yīng)用后再持續(xù)設(shè)計(jì)。

如支持不同設(shè)備或不同App版本使用不同的Bundle等等。

  • Pushy

目前官方推薦熱更新框架Pushy,可以了解下,原理都是差不多的,實(shí)現(xiàn)會(huì)更方便。

2.5 相關(guān)命令及其作用

  • Taro 轉(zhuǎn) RN
taro build --type rn
  • 調(diào)試代碼
taro build --type rn --watch
  • 打包 RN Bundle 和資源
cd rn_temp && node ../node_modules/react-native/local-cli/cli.js bundle --entry-file ./rn_temp/index.js --bundle-output ./bundle/main.jsbundle --assets-dest ./bundle --dev false

執(zhí)行 Taro 轉(zhuǎn) RN 命令后,在項(xiàng)目中會(huì)生成 rn_temp 文件夾,該文件夾即完整的 RN 代碼,打包 RN 需要進(jìn)入該目錄執(zhí)行。

打包后會(huì)生成 Bundle 文件和資源文件夾,用于替換原生保存的 RN 內(nèi)容。

三、總結(jié)

  • 友好度——轉(zhuǎn)換工作復(fù)雜度

由于作者是開(kāi)發(fā)iOS客戶端的,且于4年前已經(jīng)在現(xiàn)有項(xiàng)目中集成過(guò)React-Native頁(yè)面,對(duì)React-Native的原理和機(jī)制有過(guò)研究,實(shí)踐過(guò)相關(guān)技術(shù)棧,所以轉(zhuǎn)換工作相對(duì)容易。

對(duì)于不是客戶端出身,或者不熟悉React-Native/Weex等客戶端跨平臺(tái)框架的機(jī)制和技術(shù)棧的同學(xué),需要做點(diǎn)其他功課。

  • 多端適配以React-Native樣式為主

如果需要適配多端,需要以 React-Native 的約束來(lái)管理樣式。

因?yàn)闃邮缴?code>H5最為靈活,小程序次之,React-Native最弱(React-Native的樣式基于開(kāi)源的跨平臺(tái)布局引擎 Yoga ,樣式基本上是實(shí)現(xiàn)了 CSS 的一個(gè)子集),統(tǒng)一多端樣式即是對(duì)齊短板,也就是要以 React-Native 的約束來(lái)管理樣式,同時(shí)兼顧小程序的限制。

  • Taro-> React-Native -> iOS/Android鏈條長(zhǎng)

通過(guò) Taro 轉(zhuǎn)React-Native,React-Native再轉(zhuǎn)iOS/Android,鏈條過(guò)長(zhǎng),會(huì)面臨復(fù)雜度增加、維護(hù)成本較大、組件適配、客戶端系統(tǒng)版本和語(yǔ)言升級(jí)維護(hù)等問(wèn)題,同時(shí)影響一些復(fù)雜功能的實(shí)現(xiàn)方案的決策和估時(shí)。

毫無(wú)疑問(wèn),這是復(fù)雜度非常高的架構(gòu)設(shè)計(jì),對(duì)開(kāi)發(fā)人員的能力和各方面經(jīng)驗(yàn)有較高要求。

為了盡早覆蓋跨客戶端,Taro官方選擇 React-Native無(wú)疑是最快速和易行的方案。

  • 跨端效果和質(zhì)量

總體而言,在功能不復(fù)雜的項(xiàng)目中,進(jìn)行Taro轉(zhuǎn)換React-Native,雖然修改較多但都不算難處理,雖有幾處轉(zhuǎn)換問(wèn)題需等官方處理,但轉(zhuǎn)換后的效果和質(zhì)量還算OK。

-END-
歡迎到我的博客交流:https://zackzheng.info

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容