隨著 58 業務版圖不斷壯大,帶來的技術挑戰是怎麼在業務融合的過程中避免重複建設,提升開發以及多端落地效率,集團孵化了內部項目 58-rn,目前為止已經在組件化、開發流程優化、發布平臺建設以及線上監控預警等環節擁有一定積累。同時,Taro 是一款優秀的跨端開發框架,在 58 眾多產品線中都有使用,例如二手房、新房等。Taro 3 發布後暫不支持 React-Native 平臺,於是我們向社區提交了一份實現草案,希望把 58 在 React-Native 上的技術積累分享到社區,同時也從社區對 Taro 的共建上獲益。
鑑於 Taro 良好的可擴展架構演化,適配 React-Native 變得更加容易。本文總結一些我們在設計上的新思考,希望能夠拋磚引玉。
Taro 目前的核心流程如下所示:
(出處:https://nervjs.github.io/taro/blog/2020-07-01-taro-3-0-0/)
我們做出了一點小改變,採用 metro 直接生成 bundle 文件;這與 WEB 端的處理類似。廣義上理解,針對小程序各端的處理也基本類似,只不過中間多了一步:先編譯成目標平臺的代碼,然後再用小程序 IDE 編譯發布。當然它與前兩者還是有些差異:目標平臺的中間代碼包含 Taro 運行時,調試起來並不是非常直觀;而前兩者直接生成最終打包資源,所以天然地支持 source-map 。 這一改變帶來的好處:
更好支持項目調試;打包資源中的運行時錯誤通過 source-map 直接與項目工程代碼對應,定位問題更直觀;
Metro 更加貼合 React-Native 的打包場景:通過多級緩存以及 hasteFS 讓打包速度更快;
React-Native 社區基於 Metro 的打包優化方案對接起來更容易;
現在情況變成了:WEB 和 React-Native 直接打包;小程序則使用端平臺插件機制進行擴展,生成目標平臺代碼,需要二次編譯才能發布。框架圖後半部分更新後看起來像這樣:
在討論方案之初,我們的目標之一:Taro3 項目只要升級框架版本就可以作為 React-Native 項目運行起來,無需對 Taro 項目模板進行任何修改;這保證了業務邏輯代碼以非常低的成本在 React-Native 端進行復用。當然我們沒法保證應用的運行效果完全符合預期;例如 CSS 標準中,子元素可以繼承其父元素的樣式,這在 React-Native 中並不適用;為此,我們支持編寫針對React-Native 平臺的專屬樣式。另外,React-Native 的樣式定義是 CSS 標準的子集,所以我們在編譯時會對 React-Native 不支持的樣式給出提示以及修復建議;這樣開發者就可以逐漸熟練編寫兼容多端的樣式。 最後,如果開發者仍然希望使用 React-Native/cli 的話,只需要修改 metro 配置就可以自由切換。目前,僅支持基於 React 編寫的應用「零」成本擴展到 React-Native 端。
目前 Taro 和 React-Native 社區都主要以 WEB 開發者為主,但是側重點略有不同。Taro 主打 WEB 和小程序的融合,兼容多個應用開發框架,更偏向於小程序生態;React-Native 主打 React 生態,降低學習成本(learn once, write anywhere)。 Taro 1 和 2 做了大量工作來支持 React-Native,但是在開發體驗以及 API、組件適配程度上還需要進一步完善。我們在不影響 Taro 核心的情況下儘量解決這些痛點;例如,利用 expo 重構組件庫模塊 @tarojs/components-rn,重寫了 tab-bar 功能等。並開發獨立殼應用,本地不用配置原生開發環境也可以進行 React-Native 開發。對於 Taro 社區的開發者而言,應用可以 」無縫「 擴展到 React-Native 平臺;另一方面,React-Native 社區的開發者可以把 Taro 項目當作是 React-Native 應用的另一種項目模板,開發體驗」無縫「銜接。
最後但也是非常重要的一點,就是提升 Taro 組件和 API 規範在 React-Native 端的覆蓋度。要真正做到一套代碼,多端運行,核心在於組件 & API 規範的覆蓋度。我們支持基礎型組件(例如容器類、表單類等)的同時,也逐漸在進一步完善其它類型的組件以及 API。
tab 結構是最常用的頁面布局之一,僅僅通過 app 配置,就能生成一個多 tab 的 React-Native 頁面。
對於富有表現力的應用,總需要視頻、音頻以及相機組件的加持;我們已經把這些都集成進來了。
當下掃碼經濟如火如荼,基於開發者調研結果我們新增了 API scanCode,希望解決實際項目開發中的痛點。
React-Native 已經有非常成熟的方案來優化長列表,在此基礎上我們實現了組件 VirtualList。當開發者碰到長列表卡頓時,不妨嘗試這個新組件。
PickerView 、MovableView等。
現在分三種主要場景去闡述我們是怎麼實現「無縫「集成 React-Native 平臺的。
運行命令 yarn dev:rn 啟動 Metro bundle 伺服器時,
@tarojs/cli 通過編譯平臺擴展 presets/platforms/rn.ts,啟動@tarojs/rn-runner
@tarojs/rn-runner,它把 Taro 項目配置以及命令行參數轉換成 MetroServer 所需的配置,並與用戶自定義的 metro 配置合併(可選),然後啟動 MetroServer
MetroServer 實質還是一個 HTTP 伺服器,當發起 /index.bundle 請求時,
如果是初次請求,IncrementalBundler 會初始化 DependencyGraph,掛載 hasteFS 的 change 事件,監聽文件變更;如果是非初次請求,IncrementalBundler 會生成當前請求模塊相關的變更集
在模塊處理過程中,@tarojs/rn-transformer 會針對入口文件和頁面文件進行特殊處理,主要是支持 tab-bar、app 以及頁面配置
@tarojs/rn-style-transformer 會針對樣式進行處理,主要完成樣式語言 Sass/Less/Stylus 的覆蓋
等變更集中的模塊更新之後,重新讓當前模塊經過 Serializer 序列化成字符串返回
當我們啟動 React-Native 原生 Android 應用時(iOS類似),
CatalystInstanceImpl::runJSBundle 執行 bundle 的入口
@tarojs/runtime-rn 調用 AppRegister.registerComponent 註冊頁面,並提供 API(@tarojs/taro-rn)和組件(@tarojs/components-rn)支持
如果你已經想使用 Taro3 開發 React-Native 應用的話,步驟非常簡單:
# 注意:@tarojs/cli 最新版本還未發布,體驗版在標籤 canary 下$ yarn add @tarojs/cli@canary# 創建並初始化 Taro 項目$ npx taro init <projectName># 設置環境變量DEVTAG,安裝體驗版相關依賴:$ export DEVTAG=@canary# 啟動 Dev Server,此處會顯示監聽埠號;支持 -p 選項手動指定埠$ cd <projectName> && yarn dev:rn
下載殼應用(https://github.com/NervJS/taro-native-shell/tree/0.63.2),然後構建並安裝到模擬器或真機上(以 android 為例):
# 安裝依賴$ yarn# 構建並啟動應用 $ yarn android -- --no-packager
如果缺少原生開發環境的話,直接下載應用安裝包即可:android 地址(https://share.weiyun.com/xB4OJiBw)。
依次執行 開發者菜單 -> Bundle Location 修改 bundle 的地址為 http://localhost:\ (埠號在執行 yarn dev:rn 時會在終端中輸出)就可以看到入口頁面了。
React-Native 相關調試以及常見使用問題請參考詳細文檔(https://taro-docs.jd.com/taro/docs/3.x/react-native/)。
3.x - 升級 @tarojs/cli 最新版本;把項目中 Taro 相關依賴包升級到最新版本;然後運行 yarn dev:rn, 此時會自動安裝 React-Native 相關依賴。
2.x - 先刪除 package.json 中 已存在的 React-Native 相關依賴項(@tarojs/rn-runner、@tarojs/runtime-rn、@taorjs/components-rn、@tarojs/router-rn 以及 @tarojs/taro-rn),然後按 3.x 的升級步驟即可。
如果升級過程中碰到問題,請通過末尾附上的渠道與我們溝通進行解決。
API、組件適配註定是一項耗時費力的長期工程,我們會繼續努力提升針對 React-Native 平臺的適配度。另外,也會關注組件性能問題,讓應用的操作體驗更加流暢。
動畫是 React-Native 持續優化的重要場景,我們會充分釋放其在這方面的優勢,提升 Taro 應用的交互體驗。
目前我們主要解決了 Taro 擴展到 React-Native 端開發環節中的核心問題,後續會進一步支持項目的發布流程,集成熱更新、CI/CD 等功能。
開發過程中我們採用了靜態類型約束(TypeScript)、單元測試(jest)以及靜態分析(ESLint)等措施儘量控制代碼質量,但是仍難免會有疏漏,非常期待大家的反饋並歡迎大家一起共建。另外,Taro 也提供了微信群方便大家與維護者們更及時溝通交流:
團隊簡介: 我們是 Taro3 適配 React-Native 平臺的開發團隊,來自房產事業群的多個 BU。主要成員:陳誌慶(項目發起人+架構)、葉春喜(開發姐姐)、邢智健(android)、王信健、郝捷、祝求智、張頁飛、錢傑(ios)、解成博、楊楊(測試妹子)、杜光中、羅正龍、陳昊。