Taro React Native 3 個更新幫助開發者高效開發APP

語言: CN / TW / HK

Taro React Native 開源專案重大更新來了,全方位降低上手成本,提升開發體驗。全流程自動化,讓開發者擺脫原生環境配置,專注前端開發。

Taro 3.2.0 正式版本釋出至今,已過去半年。在此期間,有不少社群開發者已經使用上 Taro 來開發 APP 了。看到社群的使用量越來越多,開發團隊也是收穫滿滿。

同時我們也收到了很多來自開發者的反饋,主要集中於開發環境配置複雜、元件和 API 的完善度不夠及使用上的 BUG 等。對於元件和 API 的完善度及使用上的 BUG,我們都是儘可能地及時地處理併發布新版本。然而,對於開發者反饋的開發環境配置的問題,卻很難復現及解決。

首先 Android + iOS + React Native + Taro,4個技術的各種環境配置,會讓很多開發者望而卻步。其次開發者面對的環境問題千奇百怪,很多問題難以通過遠端協助解決。不少開發者在調研階段,因為無法順利執行,便放棄了使用。對於一個跨平臺框架來說,主要目的是提效,而非給開發者帶來更多困難。開發環境配置問題的解決,顯得尤為重要。

這次我們從以下三個方向去優化整個開發流程,全面降低上手成本,讓 Taro 開發 APP,變得無比輕鬆。

1、為 Taro 提供 react-native 模板,專案的初始化,只需要幾個命令。

2、與 GitHub Actions 進行整合,不再需要本地安裝原生開發環境,打包及釋出交給 CI 去做。

3、提供 Taro Playground APP,可以通過應用商店或者 GitHub 下載安裝,進行專案除錯。

 

目前使用 Taro 開發 React Native APP 時,我們需要一個原生殼工程,在另外一個倉庫[1]。對於新手來說,通常會造成一些困惑:

1、沒有接觸過 React Native 開發的開發者首先需要理解 React Native 的開發流程,然後完成兩個倉庫的初始化。

2、兩個倉庫都需要安裝依賴,並且需要保持某些依賴版本的一致性。當有依賴更新時,需要在兩個倉庫中進行操作,非常容易遺漏。

3、專案依賴原生的執行環境。開發者經常遇到安裝過程報錯,無法執行的場景。一些依賴包的下載需要切換源或依賴特定網路環境。

這些問題對新手入門很不友好,為此我們提供了一個初始化模板[2]。初始化專案使用 taro init [project] 選擇 react-native 模板。

初始化完成後,便可使用進入開發。以下為一些常用命令:

# 更新相關依賴。在初始化完成後或 Taro 版本更新後執行,用於同步 peerDependencies。
$ yarn upgradePeerdeps

# 打包 js bundle 及靜態資源。在初始化完成後執行,用於打包預設使用的 bundle。
$ yarn build:rn --platform ios

# 啟動 bundle server
$ yarn start

# 啟動 iOS
$ yarn ios

# 啟動安卓
$ yarn android

具體操作可以檢視錄屏:

 

 

通過模板方式進行初始化的專案,有幾個優勢:

1、Taro 倉庫與殼工程倉庫進行整合,不再需要管理雙倉庫。當然習慣雙倉庫模式的開發者,仍然可以正常使用。

2、當 Taro 進行升級時,可以通過執行 yarn upgradePeerdeps進行依賴同步。這裡我們將 Taro 依賴的 React Native 相關庫寫入了 peerDependencies 中,然後通過 install-peerdeps 去完成依賴的同步。

3、集成了 GitHub Actions,可通過 workflow 完成 APP 的打包。

 

要解決開發環境的各種問題,通常的做法就是提供一個穩定的環境用於打包釋出,在企業裡是各種 CI/CD 平臺。但對於開源專案來講,就需要一個公開的平臺,每個人都能使用,當然最好是免費的。於是我們想到了 GitHub Actions。

GitHub Actions 是 GitHub 提供的持續整合服務,於 2018 年 10 月推出。功能非常強大,並且免費(每月有限額),同時私有倉庫也能夠使用,非常契合我們的需求。

通過模板初始化的專案,可在 .github/workflows 目錄中看到 4 個檔案。分別為 iOS 和 Android 的 release 包和 debug 包的打包工作流。模板為了簡化過程,設定為通過 git push 即可觸發打包,可根據自身情況,配置合適自身業務場景的工作流。打包生成的產物可以在 Artifacts 中找到,也可以使用 softprops/action-gh-release@v1 action,將產物釋出到專案的 Release 中。

這樣一來新手便可以不需要關注原生環境以及 APP 打包的問題。開發時,可以安裝 debug 包載入本地的 jsbundle,進行除錯。釋出時,交給 CI 進行打包,產物再提交到應用市場,整個過程完全不需要 AS 與 XCode。當然這裡還有一些必要配置需要做,比如 APP 的簽名等,將在後面的章節講解。

GitHub Actions 功能非常強大,Taro 就用它來做打包釋出等工作,可參考文件[3]或檢視資料做進一步探索,做點有趣的事情。

 

在 Taro 專案模板裡面我們提供了一個 CI 指令碼模板,開發者仍然需要進行一些配置,才能夠開始打包。下面是打包 Android APP 的基礎配置說明,iOS 同理:

  • 配置打包的環境變數

env:
    APP_ID: com.taro.demo  # 應用 ID
    APP_NAME: Taro Demo  # 應用名稱
    VERSION_NAME: 1.0.0 # 應用版本號
    VERSION_CODE: 10 # 用於應用市場、程式內部識別版本,判斷新舊版本,一般遞增處理
    KEYSTORE_FILE: debug.keystore # 簽名檔案
    KEYSTORE_PASSWORD: android # 密碼
    KEYSTORE_KEY_ALIAS: androiddebugkey # 別名
    KEYSTORE_KEY_PASSWORD: android # 別名的密碼
  • 通過 github secrets 管理祕鑰配置

     

    通常我們不應該把金鑰等敏感資訊直接寫在配置檔案中,而是置於加密資訊中。在 GitHub Actions 中,可以使用加密機制進行處理[4]。如圖,在 setting -> secret 配上 CI 需要的 secret。然後在 workflow 中通過相應變數進行使用,如 ${{secrets.DEBUG_KEYSTORE_PASSWORD}}。

 

對於殼工程與專案工程分開的場景,利用 CI 命令將兩個專案進行合併也可以實現打包自動化。具體流程如下:

1、殼工程和業務專案合併

因為 GitHub Actions 只能在當前專案下進行操作,所以需要將殼工程(taro-native-shell)合併到專案工程下。

2、合併專案和殼工程的 package.json

在有原生依賴的情況下,必須保證殼工程和業務專案的原生依賴版本一致,不然打包可能會報錯。

3、安裝依賴

在業務專案工程下安裝合併後的 package.json 依賴。

4、軟鏈依賴

將安裝到業務專案下的依賴軟鏈至殼工程專案 node_module 下。

ln -s ./node_modules ./taro-native-shell/node_modules

5、業務專案編譯

執行 taro/cli build:rn 編譯命令,打包生成 jsbundle 與靜態資源。

6、將編譯產物移動到原生殼工程

rn: {  appName: 'taroDemo',  output: {    ios: './ios/main.jsbundle',    iosAssetsDest: './ios',    android: './android/app/src/main/assets/index.android.bundle',    androidAssetsDest: './android/app/src/main/res',    iosSourcemapOutput: './ios/main.map',    androidSourcemapOutput: './android/app/src/main/assets/index.android.map',  },}

taro 編譯 rn 輸出靜態資源,需要將資源移到原生專案中。

7、編譯原生 APP

到 ios 和 android 目錄裡分別執行對應的打包命令。

8、上傳 APP

將打包後的 APP 進行上傳,提供下載連結。

# iOS- name: Upload iOS Products  uses: actions/[email protected]  with:    name: app-${{ env.BUILD_TYPE }}    path: |      ${{ github.workspace }}/ios/taroDemo.ipa      ${{ github.workspace }}/ios/taroDemo.app.dSYM.zip

 

# Android- name: Upload Android Products  uses: actions/[email protected]  with:    name: app-${{ env.BUILD_TYPE }}    path: ${{ github.workspace }}/android/app/build/outputs/apk/${{ env.BUILD_TYPE }}/app-${{ env.BUILD_TYPE }}.apk

在 iOS 側,release workflow 還集成了上傳至 APP Store 命令:

- name: Upload app to App Store Connect  env:    APP_STORE_CONNECT_USERNAME: ${{ env.APP_STORE_CONNECT_USERNAME }}    APP_STORE_CONNECT_PASSWORD: ${{ env.APP_STORE_CONNECT_PASSWORD }}  run: |    cd ios    xcrun altool --upload-app -t ios -f "taroDemo.ipa" -u "$APP_STORE_CONNECT_USERNAME" -p "$APP_STORE_CONNECT_PASSWORD"

上面整個流程對於開發者來說理解成本太高,配置過於繁瑣,所以我們將前 6 個步驟封裝成一個 GitHub action[5],開發者只需要新增一些配置項就能完成上面的流程。

- name: taro-native-publish  uses: shinken008/[email protected]  with:    REPO: ${{ env.SHELL_REPO }}    REPO_REF: ${{ env.SHELL_REPO_REF }}    REPO_PATH: taro-native-shell    BUILD_CMD: yarn build:rn    IOS_BUNDLE: ios/main.jsbundle    IOS_ASSETS: ios    ANDROID_BUNDLE: android/index.android.bundle    ANDROID_ASSETS: android    PLATFORM: android

對應的需要拉取的另一個倉庫的配置:​​​​​​​

env:  # 殼工程  SHELL_REPO: NervJS/taro-native-shell  # 殼工程ref  SHELL_REPO_REF: 0.63.2  # 殼工程目錄  SHELL_REPO_PATH: taro-native-shell

配置介紹:

  • REPO:殼工程地址

  • REPO_REF:殼工程分支

  • SHELL_REPO_PATH:殼工程目錄

  • IOS_BUNDLE:編譯 iOS 後的 js bundle 地址

  • IOS_ASSETS:編譯 iOS 後的其他靜態檔案(圖片等)地址

  • ANDROID_BUNDLE:編譯 Android 後的 js bundle 地址

  • ANDROID_ASSETS:編譯 Android 後的其他靜態檔案(圖片等)地址

  • PLATFORM:編譯的目標平臺 ios/android

     

iOS APP 的打包過程相對繁瑣,這裡我們直接使用了一個優秀的工具 fastlane[6]。fastlane 是一個為 iOS 和 Android 開發者提供的工具,可以自動執行繁瑣的任務,如生成螢幕截圖、處理配置檔案和釋出應用程式。

打包過程中的 info plist 檔案修改、版本號修改、簽名設定都可以交給 fastlane 去處理,經過 fastlane 的封裝,開發者處理這些繁瑣的任務,只需要新增幾行配置即可。

但是要讓 fastlane 在 GitHub Actions 使用,還需要幾步操作。因為證書(Certificate)與描述檔案(Provisioning Profiles)並不儲存在專案倉庫中,而每次工作流都是發生在隨機的主機上的,這就需要我們在打包前,先將證書與描述檔案匯入到當前主機中。

Release 證書的匯入過程如下:

1、將證書的 p12 檔案轉成 base64 字串。

cat Certificates.p12 | base64 | pbcopy

2、將第一步內容儲存在專案的 secret 中,key 為 RELEASE_SIGNING_CERTIFICATE_P12_DATA

3、將p12 檔案的密碼儲存在專案的 secret 中,key 為 RELEASE_SIGNING_CERTIFICATE_PASSWORD

4、將 secret 內配置的相關資訊匯入到主機中。​​​​​​​

security import <(echo $SIGNING_CERTIFICATE_P12_DATA | base64 --decode) \    -f pkcs12 \    -k build.keychain \    -P $SIGNING_CERTIFICATE_PASSWORD \    -T /usr/bin/codesign

 

描述檔案的匯入過程,與證書的匯入過程類似,均已封裝在 workflow 中。

要將生成的 ipa 檔案上傳至 testflight 或者 APP Store 上,還需要提供使用者名稱(APP_STORE_CONNECT_USERNAME)與密碼(APP_STORE_CONNECT_PASSWORD),可參考文件進行生成[7]。

至於證書與描述檔案的生成,可查閱 iOS 開發相關文章[8],這裡不再贅述。fastlane 配置的更多細節可檢視 ios/fastlane/Fastfile 檔案。

 

Android 的打包過程相對簡單,直接呼叫 gradlew 命令即可。除了配置 APP 的基礎資訊,還需要為應用進行簽名。可參考 Android 應用簽名相關文件[9],生成簽名檔案,置於 android/app 目錄中。

簽名檔案也可通過命令列工具生成:

keytool -genkey -alias android -keyalg RSA -validity 99999 -keystore release.keystore

打包相關引數,通過 gradlew 的 -P, --project-prop 引數進行傳入,如 ./gradlew assembledebug -Papp_id=${{ env.APP_ID }},其預設值在 android/gradle.properties 檔案中定義。

 

基於 GitHub Actions 與 Taro 模板,我們完成了專案初始化與打包過程的自動化。但對於想要體驗 Taro 開發 APP 的開發者來說,仍然太過繁瑣。為此,我們開發了 Taro Playground APP,並完全開源[10]。一方面可以展示元件和 API 的使用示例,另一方面提供了動態載入 jsbundle 的功能,便於開發人員進行原生代碼的除錯。 

 

本地除錯 

開發者可以在 Taro Playground 倉庫的 Releases 頁面進行安裝包下載[11],也可掃描以下二維碼安裝 APP。

Android iOS

Taro 工程中通過 yarn dev:rn --qr 啟動 bundler server,列印包含 IP 及埠資訊的二維碼。通過 Taro Playground APP 掃描該二維碼,即可載入 jsbundle 進行除錯,需要保證手機與電腦處於同一個區域網中。

具體操作可以檢視錄屏:

 

 

 

示列程式碼

Taro Playground 專案提供了較全面的示例程式碼,開發者可以參考,避免一些可能遇到的坑,如有問題,歡迎 pr。

​​​​​​​

 

通過上述多方面的優化,極大地降低了使用 Taro 開發 APP 的成本。大部分場景下,只需要掌握 Taro 和 React Native,再加上一些配置,即可完成 APP 的開發與釋出。

使用過程中,如遇任何問題,可新增 “58技術小祕書” 或 “Taro 小助手” 為好友,備註 “Taro RN”,加入官方交流群尋求幫助。

後續,我們還將帶來支援 React Native 的 Taro UI 以及包含詳細教程的技術小冊,盡請期待。

同時我們也在徵集社群優秀使用案例,歡迎開發者提交案例到案例倉庫中[12]。

 

相關連結:

[1] 殼工程地址:https://github.com/NervJS/taro-native-shell

[2] 模板原始碼地址:https://github.com/NervJS/taro-project-templates/tree/v3.1/react-native

[3] GitHub Action 文件:https://docs.github.com/cn/actions

[4] GitHub Action 加密機制:https://docs.github.com/cn/actions/reference/encrypted-secrets

[5] Taro React Native Publish Action:https://github.com/shinken008/taro-native-publish

[6] fastlane官網:https://docs.fastlane.tools

[7] AppleID 密碼生成:https://support.apple.com/en-us/HT204397

[8] 使用 GitHub Action 釋出 iOS 應用:https://betterprogramming.pub/deploy-an-ios-app-to-testflight-or-the-app-store-using-github-actions-c4d7082b1430

[9] 安卓簽名檔案生成:https://developer.android.com/studio/publish/app-signing#generate-key

[10] Taro Playground 原始碼:https://github.com/wuba/taro-playground

[11] Taro Playground APP 下載:https://github.com/wuba/taro-playground/releases

[12] Taro 案例提交:https://github.com/NervJS/taro-user-cases

 

作者簡介:

陳誌慶:58同城 前端架構師,技術委員會委員

王信健:58同城 資深前端開發工程師

 

鳴謝:

謝偉:iOS 整合

趙尉尉:Android 整合

解成博:Taro Playground APP 開發

楊楊:Taro Playground APP 測試

相關連結