React使用詳解


Li Zheng [email protected]

React 並不是簡單地在 Javascript 中嵌入 HTML ,而是對 UI (包括 web 和 APP)渲染的方式進行了革新。而且, 選擇 React 是商業問題而不是技術問題

本文的工具安裝以 Linux 爲例,其它平臺詳見 開始使用React Native - react native 中文網

安裝 node.js 及其自帶的包下載工具 npm

nodejs 官網 下載安裝。

如果是 Linux 用戶,需要手動將 node 安裝位置的 bin 目錄添加到 $PATH 中。

配置 npm 鏡像

爲避免後續執行 npm install 時因網絡問題導致的下載失敗,最好是配置一下鏡像:

npm config set registry https://registry.npm.taobao.org

安裝 watchman

watchman 是由 Facebook 提供的監視文件系統變更的工具。安裝此工具可以提高開發時的性能( React Native 的 packager 可以快速捕捉文件的變化從而實現實時刷新)

安裝依賴

sudo apt-get install autoconf automake python-dev libtool pkg-config libssl-dev

安裝 watchman, 如果出錯, 查看安裝依賴的詳細文檔

git clone https://github.com/facebook/watchman.git
cd watchman
git checkout v4.6.0  # 也可以是其它的最新版本號
./autogen.sh
./configure
make
sudo make install

安裝 flow

flow 是一個靜態的 js 類型檢查工具。你在很多示例中看到的奇奇怪怪的冒號問號,以及方法參數中像類型一樣的寫法,都是屬於這個 flow 工具的語法。這一語法並不屬於 ES 標準,只是 Facebook 自家的代碼規範。所以新手可以直接跳過(即不需要安裝這一工具,也不建議去費力學習 flow 相關語法)。

在終端中輸入以下命令來安裝flow:

npm install -g flow-bin

項目名稱限制

項目名稱中不能有 - 這個符號。

安裝 react-native-cli

npm install -g react-native-cli

創建 react-native 項目

比如項目名稱爲 AwesomeProject :

react-native init AwesomeProject

這會自動創建 AwesomeProject 目錄及其中一些文件。

從 react 15.3.0 開始,容易在應用的界面上引發巨量的 warning “You are manually calling a React.PropTypes validation” ,而且這些 warning 在 react 16 中將會變成 error ,在其它一些 react-native 第三方庫解決這些問題(能使用 react 16 了)之前,可以先只用 react 15.2.1 ,所以可以指定安裝依賴於 react 15.2.1 的最後一個 react-native 版本 0.31.0 :

react-native init --version 0.31.0 AwesomeProject

配置 Android 開發環境

https://developer.android.google.cn/studio/index.html 下載 sdk-tools-linux 成爲比如 ~/tools/android-sdk/ ,在 ~/.bashrc 中添加 export ANDROID_HOME=~/tools/android-sdk 。後續在編譯各種 APP 時 ~/tools/android-sdk/tools/bin/sdkmanager 會視需要自動下載比如 ~/tools/android-sdk/platforms/android-26/ 等,如果在自動下載時出現 “You have not accepted the license agreements of the following SDK components” 的錯誤,則需手動運行一下 yes | ~/tools/android-sdk/tools/bin/sdkmanager --licenses

爲了讓 android-sdk 中 32 位的 aapt (比如 ~/tools/android-sdk/build-tools/26.0.0/aapt ) 能夠在 64 位的 Linux 中運行,還要確保已經運行過如下命令:

sudo apt install lib32stdc++6 lib32z1

如果沒有裝過 jdk 的話,還需要:

sudo apt install default-jdk

如果 echo $SHELL 發現是 dash 的話,後續編譯時會報 aapt: Syntax error: newline unexpected (expecting ")" 的錯誤,所以還需換成 bash:

sudo dpkg-reconfigure dash

如果是 Win10 中的 WSL ,後續編譯時會報 aapt: cannot execute binary file: Exec format error 的錯誤,這是由於 64 位的 Win10 只支持 64 位而不支持 32 位的 Linux 二進制可執行文件 ,解決方法是先

sudo apt install qemu-user

然後以 ~/tools/android-sdk/build-tools/23.0.1/aapt 爲例,把 aapt 重命名爲 aapt-32 ,最後原地新建可執行腳本文件 aapt ,腳本內容爲 qemu-i386 ~/tools/android-sdk/build-tools/23.0.1/aapt-32 $* 即可。

debug 在線運行 Android

在 react-native 項目目錄比如 AwesomeProject/ 中用如下命令自動編譯 apk 並運行:

react-native run-android

它也會同時啓動 native packager server , 如果沒有自動啓動 server , 會報錯 React Native: ReferenceError: Can't find variable: require (line 1 in the generated bundle) ,此時就需要手動啓動:

react-native start

這樣,當 js 代碼修改後,將 Android 真機搖一搖,就能 Reload 過來最新修改的 js 代碼了。

如果 react-native run-android 出現錯誤提示 “java.util.concurrent.ExecutionException: com.android.builder.utils.SynchronizedFile$ActionExecutionException: com.android.ide.common.signing.KeytoolException: Failed to create keystore.” ,則需要

keytool -genkey -v -keystore debug.keystore -storepass android -alias androiddebugkey -keypass android -keyalg RSA -keysize 2048 -validity 10000

並將生成的 debug.keystore 放到 ~/.android/ 中。

如果 react-native start 出現錯誤提示 “increase the fs.inotify.max_user_watches sysctl” ,則可按 Increasing the amount of inotify watchers 進行操作。

如果是 Win10 中的 WSL ,由於 Windows 的防火牆無法自動在 WSL 中的 Linux 開啓端口時彈出對話框讓用戶選擇是否允許,所以只有 Win10 本機才能訪問該端口。爲了讓其它主機比如 Android 真機搖一搖後 Dev Setting | Debug server host & port for device 設置能夠成功 Reload 到 js 代碼,需要手動在防火牆中開啓 native packager server 所監聽的 8081 端口,方法是在 控制面板 | Windows Defender 防火牆 | 高級安全 Windows Defender 防火牆 | 入站規則 | 新建規則 中選擇 端口 | 8081 | 允許連接 ,最後填寫名稱比如爲 Allow localhost port 8081 以及填寫描述比如爲 port forwarding to allow external machine to access Windows 10's Windows Subsystem Linux servers 即可。

release 離線打包 Android

生成簽名庫,拷貝至 android/app/

keytool -genkey -v -keystore rn-apk.keystore -alias rn-apk -keyalg RSA -keysize 2048 -validity 10000

設置全局變量 ~/.gradle/gradle.properties

MYAPP_RELEASE_STORE_FILE=rn-apk.keystore
MYAPP_RELEASE_KEY_ALIAS=rn-apk
MYAPP_RELEASE_STORE_PASSWORD=130777
MYAPP_RELEASE_KEY_PASSWORD=130777

更改 android/app/build.gradle

signingConfigs {
    release {
        storeFile file(MYAPP_RELEASE_STORE_FILE)
        storePassword MYAPP_RELEASE_STORE_PASSWORD
        keyAlias MYAPP_RELEASE_KEY_ALIAS
        keyPassword MYAPP_RELEASE_KEY_PASSWORD
    }
}
buildTypes {
    release {
        ...
        signingConfig signingConfigs.release
    }
}

生成 apk

cd android
./gradlew assembleRelease

如果在此過程中報出 Out of Memory Error 的錯誤,則需要在 ~/.gradle/gradle.properties 中添加類似如下內容:

org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8

更多用法參見 React-Native 離線打包

release 在線更新

參見 React Native CodePush實踐小結

安裝 react-dom

安裝後續要安裝的 react-web 的 package.json 中的 peerDependencies 裏的 reactreact-dom,因爲 react-web 相當於是 reactreact-dom 這兩個宿主的插件,想要裝插件就要先裝宿主。由於上面 react-native init 已經自動安裝了 react ,所以現在只需安裝 react-dom ,如果後續某個新版的 react-web 也許也能像現在 react-native 自動安裝 react 一樣去安裝 react-dom,則此處可省:

cd AwesomeProject
npm install react-dom --save

安裝 react-web

npm install -g react-web-cli

另:官方 react-web 已停止維護,可使用我維護的 https://github.com/flyskywhy/react-web 替代,或是參考另一套 https://github.com/necolas/react-native-web 。

創建 react-web 項目

cd ..
react-web init AwesomeProject

運行 Web

運行如下命令即可啓動 webpack 調試服務器,然後在瀏覽器打開 localhost:3000 即可:

react-web start

坑:有時修改了 js 文件但是 webpack 調試服務器沒有自動重新 bundle ,這個 BUG 可以通過重啓電腦解決。

其它可參見 三步將 React Native 項目運行在 Web 瀏覽器上面

打包 Web

react-web bundle

打包完成後,文件會存放在 web/output/ 目錄下面。

配置 iOS 開發環境

除了爲 React Native 搭建開發環境 ,還需 像 Mac 高手一樣管理應用,從 Homebrew 開始 使用 brew installbrew cask installmas install 安裝各種實用工具。安裝過程中最好保持翻牆狀態,否則速度較慢或無法安裝。另可參考 我在 Mac 上都用什麼 一文。

brew install mas node watchman
brew cask install sublime-text double-commander google-chrome the-unarchiver iterm2 xquartz typora meld dos2unix intelliscape-caffeine bitbar geektool turbovnc-viewer microsoft-remote-desktop-beta flux mosh inkscape gimp

注:其中 turbovnc-viewer 的運行需要先安裝下面提到的 JAVA 環境,並在 macOS 自帶終端中運行(在 iterm2 中運行沒有效果)如下語句:

export JAVA_HOME=`/usr/libexec/java_home -v 1.8`
launchctl setenv JAVA_HOME $JAVA_HOME
  • 解決 brew installnpm install -g 時出現的 /usr/local/ 權限問題

如果當前不是 macOS 的第一個用戶,就算已加入 admin 組,也還需要手動加入 wheel 組:

sudo dseditgroup -o edit -a $USER -t user wheel
  • 解決 brew install 卡住很久的問題

brew 在安裝軟件前會先嚐試升級 brew 自身,這裏可能是中國網絡環境的原因而會卡住很久,如果不想要升級 brew 自身的,此時可以直接 CTRL + C 跳過,它就會自動繼續去安裝了。

  • 解決 brew install 的 git-gui 運行時容易崩潰的問題

使用其它 git 的圖形化客戶端替代,比如

brew cask install fork
  • 安裝 JAVA 環境

如果想在 macOS 上編譯 Android APP ,則還需參考 macOS 的 JDK 安裝問題 (Homebrew) 一文安裝 JDK8

brew cask install AdoptOpenJDK/openjdk/adoptopenjdk8

Xcode 編譯過程問題集錦

  • 手工下載 node_modules/react-native/third-party

如果出現這個錯誤

Failed to successfully download 'boost_1_63_0.tar.gz'. Debug info:
ls: /Users/lizheng/Library/Caches/com.facebook.ReactNativeBuild/boost_1_63_0.tar.gz: No such file or directory

則要按照 node_modules/react-native/scripts/ios-install-third-party.sh 中底部的幾個鏈接手動下載,再將下載好的文件放到 ~/.rncache/~/Library/Caches/com.facebook.ReactNativeBuild/ 中即可用 Xcode 重新編譯。

另:如果按後文所說“使用 Cocoapods 安裝 iOS 第三方庫”,則不會存在本問題。

  • ‘RCTAssert.h’ file not found

這是 react-native 最基本的一個 .h 文件,也會報錯,對於蘋果公司的產品真是無語了。這一般是因爲 Xcode 或 macOS 的 bug ,重啓 macOS 就可以了……如果使用外接鼠標的話,有時 macOS 突然會變得很卡,很難用鼠標進行移動、點擊等操作,換個鼠標仍然如此,也是重啓 macOS 就可以了,或是將鼠標接收器換個 USB 口,但如果換了,剩下的那個 USB 口有時無法正常連接 iPhone 進行調試……

  • 儘量在 Xcode 中編輯文件內容

否則 Xcode 會不知道文件已經編輯過了。如果是在 Xcode 中編輯的話, Xcode 會自動 index 一下,然後 build 時就不會出錯了。再次吐槽的是, index 和 build 的速度也太慢了。

  • Timeout waiting for modules to be invalidated

曾經在模擬器中安裝調試運行時碰到過這個錯誤,按 https://stackoverflow.com/questions/46206867/timeout-waiting-for-modules-to-be-invalidated 中的說法是需要將真機的 WiFi 連到與 macOS 同一個局域網中,不過我的情況是將模擬器換成真機後就好了,搞不懂背後真正的原因是啥。

  • 真機調試時需要在 Xcode 的菜單 Preferences | Accounts 那裏添加 Apple ID ,並在 Xcode 的主界面中的 Project 的某個 Target 的 ‘Signing & Capabilities’ 那裏選擇相應的 Team 。

但是,千萬要記得所添加的那個 Apple ID 就是今後將要用來發布到 App Store 的賬號,否則如果先用自己個人的免費賬號在真機上進行調試了,那麼蘋果服務器就會自動將你所調試的 APP 的 PRODUCT_BUNDLE_IDENTIFIER 比如 com.domainname.appname 作爲 APP ID 保存到你的個人賬號名下了,那樣等你後續用公司的收費賬號在 https://developer.apple.com/ 上申請 Identifiers 時,它就會說 “An App ID with Identifier ‘com.domainname.appname’ is not available” ,而你用免費賬號登錄 https://developer.apple.com/ 的話根本連 Identifiers 的進入按鈕都看不見更別說刪除該 APP ID 了,這樣你只能讓你的公司賬號下的 PRODUCT_BUNDLE_IDENTIFIER 改名……蘋果公司又一個反人類的設計。

第一次打包 APP 以便在真機上運行時, Xcode 會彈出對話框讓你輸入蘋果電腦登錄密碼以便訪問鑰匙串,你確定一次後,又回彈出一次,再確定,再彈出,次數多到讓你以爲你輸錯了蘋果電腦登錄密碼……一共會彈出 10 次左右的對話框……

  • 添加 Apple ID 時報錯說“未知錯誤”

如果局域網不太穩定(比如路由器再加一個 WiFi 放大器)就容易出現這個問題,可以通過臨時連接手機熱點來簡單解決之。

  • 開發時也需要連接蘋果公司服務器

在 Xcode 中點擊 Run 按鈕第一次將 APP 在真機上運行時,當真機界面上出現 APP 圖標時, Xcode 會彈出對話框,按照其提示到真機的 設置 | 通用 | 設備管理 | 開發者 APP 中進行驗證,然而接着關閉 Xcode 中的對話框後, Xcode 並不會接着繼續啓動 APP 進行調試,如果你想在 Xcode 中看到調試信息的話,你就不得不再次點擊 Run 按鈕自動 build 安裝共 3 分鐘後纔行,真是浪費生命。而更弔詭的是,如果後續某個時間你的路由器因某種原因與互聯網連接斷開,那麼連接在路由器的 WiFi 上的真機中的 APP 又變成了需要驗證的狀態,也就是你沒有互聯網的話就連代碼調試都無法做到,蘋果公司的服務器時刻在看着你……

  • 用 Debug 配置進行調試

由於使用 Release 配置點擊 Run 按鈕的話需要等待半小時,所以調試時記得將 Produce | Scheme | Edit Scheme | Run | Build Configuration 設置爲 Debug 。其實就算使用 Debug ,運行也需要 3 分鐘,哪像 react-native 開發時只需要手機搖一搖花 3 秒鐘就能看到 JS 代碼所做的改變。真爲那些全部代碼都使用 Xcode 原生編寫的開發人員感到悲哀——每天不知道浪費了多少個 3 分鐘。還好我只需要捏着鼻子偶爾用連語法都是反人類的 ObjectC 語言在 Xcode 中做一些原生適配,就又可以愉快地去寫 JS 代碼了。

  • 項目所在絕對路徑中不應該有空格,否則編譯會失敗

  • 配置 node 路徑

如果沒有標準化安裝 nodejs ,比如 brew install node@10 這種方式安裝的,則就算已經在 .bash_profileexport PATH=/usr/local/opt/node@10/bin:$PATH 了,也還是會在真機編譯時報 Can't find 'node' binary to build React Native bundle 這樣的錯誤,此時需要按提示到 Xcode 的 Project 的 Build Phases | Bundle React Native code and images 那裏將 export NODE_BINARY=node 改爲 export NODE_BINARY=$(which node) 。或者還有一種方法 ln -s $(which node) /usr/local/bin/node

  • 爲 Xcode 添加 iOS-DeviceSupport

如果真機調試運行時出現比如 This iPhone 7 (Model 1660, 1778, 1779, 1780) is running iOS 13.2.3 (17B111), which may not be supported by this version of Xcode. An updated version of Xcode may be found on the App Store or at developer.apple.com. 這樣的錯誤提示,它的意思是當前版本的 Xcode 不支持真機上的 iOS 操作系統版本。調試一個手機 APP 還必須要 IDE 支持手機操作系統的版本,這樣的反人類設計恐怕也只有蘋果公司才做得出來。可以如提示中所說升級 Xcode 自身,但 Xcode 安裝包要 7 個多 GB ,而且偶爾某個版本的 Xcode 會出現一些奇奇怪怪的 BUG ,所以最簡潔的方式其實是爲當前版本的 Xcode 的安裝目錄某個地方多添加一個比如 13.2 目錄即可。

從 https://github.com/iGhibli/iOS-DeviceSupport/tree/master/DeviceSupport 下載比如 13.2(FromXcode11.2.1(11B500)).zip ,解壓出 13.2 目錄, sudo mv 13.2 /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/ ,最後重啓 Xcode 並重連手機即可。

  • dyld: Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.66.dylib

如果在 Xcode 持續開啓的狀態下,比如爲了滿足 App Store 上預覽視頻的分辨率要求而在終端裏 brew install ffmpeg 用於視頻轉碼,然後一轉眼 Xcode 運行 Product | Archive 打包到 node 步驟時即可能報上述錯誤,其原因是 node 和 ffmpeg 都依賴 icu4u ,而一般情況下 node 是比較早之前安裝的,那時候自動安裝的 icu4u 版本如果比現在 ffmpeg 觸發安裝的 icu4u 版本舊的話,就會出現本問題。解決的方法是重新啓動 Xcode 。

App Store 反人類集錦

  • 難以理解的開發證書、生產證書、描述文件

不像 Android 的 apk 只需要命令行生成一個 key 用來簽名就可以發佈到 Google PLAY 了,你需要浪費生命中的幾個小時甚至幾天來理解 iOS開發證書、bundle ID、App ID、描述文件、p12文件,企業證書打包發佈,及過期處理iOS開發者證書申請及應用上線發佈詳解ios開發證書的坑 這些文章並進行相關操作。

其中一個需要理解的是, Xcode 第一次連接真機進行調試時,它會詢問你是否將真機加入設備列表以便放入描述文件,在你點擊確定後,它其實偷偷摸摸將你的真機的 UUID 放到了 https://developer.apple.com/account/resources/devices/list ,並且自動爲你生成了調試用的描述文件,裏面內含真機的 UUID 信息,也就是說使用這個描述文件打包的 APP 只能在這個真機運行,而 https://developer.apple.com/account/resources/profiles/list 中的是發佈用的描述文件,裏面不含真機的 UUID 信息,也就是說使用這個描述文件打包的 APP 可以在任何設備上運行。所以我們不用關心網頁上的設備列表,只需要關心在網頁上創建描述文件並下載以便發佈即可。

  • 沒有提示自動審覈

如果在 Xcode 中用 Window | Organizer | Distribute App 成功上傳到了 App Store 中,但卻無法在 https://appstoreconnect.apple.com/ 的任何地方找到該構建版本的信息,這一般是因爲蘋果公司服務器自動審覈你上傳的 ipa 後發現了問題,所以你需要到相關郵箱中等待蘋果公司服務器自動發來的電子郵件。問題是沒有任何提示告訴你需要到郵箱中等待……

  • 不會自動選擇構建版本

即便你解決了自動審覈提出的問題,也重新上傳到 App Store 中了,而且也能在 https://appstoreconnect.apple.com/ 的 TestFlight 和活動中看到該構建版本的信息了,但你還是需要去點擊“構建版本”文字旁邊的 + 號進行選擇才能準備“提交以供審覈”。

  • 出口合規證明信息

需要到 https://appstoreconnect.apple.com/ 的 TestFlight 中進行“出口合規證明信息”,說是

您的 App 是否使用加密?即使您的 App 只使用了 Apple 操作系統中的標準加密,也請選擇“是”。
如果您正在使用 ATS 或調用 HTTPS,則您必須向美國政府提交年終自行分類報告。

不過正像 https://stackoverflow.com/questions/45008590/itunesconnect-requires-me-to-submit-year-end-self-qualification-report 裏面有人提到的,如果美國政府相關機構不對我們的申請進行回覆,難道就不上架 App Store 了?實際上從 App Store 上架關鍵步驟:出口合規信息、內容版權、廣告標識符的選擇 一文來看,這個現在可能已經沒人真正去管了。所以我們可以按照 iOS app TestFlight 缺少出口合規證明 所說在 Info.plist 中設置 <key>ITSAppUsesNonExemptEncryption</key><false/> 鍵值對,這樣我們下次上傳構建版本後就不會看到這個“出口合規證明信息”了。

  • App 預覽和截屏

要上傳或查看預覽視頻,只能使用 Safari 瀏覽器,用 Chrome 都不行……

App Store 更新 APP 流程

前文提到了首次上架 APP 時的一些繁瑣操作。這裏再簡單羅列下更經常用到的更新 APP 的流程,以儘量從蘋果公司手裏挽回點寶貴的生命……

在 https://appstoreconnect.apple.com/apps 中的 “App Store” 那裏新增一個版本號比如 1.2 ,並在 project.pbxproj 中的 MARKETING_VERSION (也就是 Xcode 的主界面中的 Project 的某個 Target 的 General 那裏的 Version )處也寫上相同的版本號 1.2 ,以及在 CURRENT_PROJECT_VERSION (也就是 Xcode 的主界面中的 Project 的某個 Target 的 General 那裏的 Build )中寫上比如 1.2.0 (如果審覈被拒了,只要簡單修改成比如 1.2.1 就可以再次上傳)

cd ios
pod install

在 Xcode 的主界面中的 Project 的某個 Target 的 ‘Signing & Capabilities’ 那裏選擇相應的 Team 。

將 Xcode 菜單 Produce | Scheme | Edit Scheme | Run | Build Configuration 設置爲 Release 。

在 Xcode 運行 Product | Archive 打包。

在 Xcode 中用 Window | Organizer | Distribute App 上傳到 App Store 中。

上傳後可以在 https://appstoreconnect.apple.com/apps 中的 “活動” 那裏看到正在被自動審覈(如果沒看到,就要去查你的郵箱是否有蘋果公司發來的郵件了),然後大概幾分鐘後自動審覈成功,就能在 “App Store” 那裏的 “構建版本” 旁邊看到出現一個 + 號了,點擊選擇後,並且填寫 “此版本的新增內容” ,就可以點擊“存儲”和“提交以供審覈”按鈕了。

使用 Cocoapods 安裝 iOS 第三方庫

首先是安裝 cocoapods 自身

sudo gem install cocoapods

ios/ 目錄中運行 pod init 以生成 Podfile 文件,然後可以按需修改,推薦按照下面會提到的 react-native-unimodules 的 README.md 說的那樣修改 ios/Podfile 。除了 react-native-unimodules 外,在 [email protected] 及更高版本一般是不需要修改 ios/Podfile 的。

最後就可以這樣簡單地安裝 iOS 第三方庫了(而不是像前文那樣還要手工下載 node_modules/react-native/third-party ):

pod install

安裝完後它會提示退出 Xcode 進程,並且下次 Xcode 啓動後需要 Open another project... 打開 ios/ 目錄中的 .xcworkspace 而非 .xcodeproj

使用 pod install 方式的話,就不需要再運行以前安裝 react-native 第三方組件經常所需的 react-native link 命令,如果曾經運行過,則需要 react-native unlink

如果 pod install 速度很慢或者乾脆無法完成,可以參考 清華大學開源軟件鏡像站 CocoaPods 鏡像使用幫助

cd ~/.cocoapods/repos
pod repo remove master
git clone --depth 1 https://mirrors.tuna.tsinghua.edu.cn/git/CocoaPods/Specs.git master

後續如果想要更新,只需

cd ~/.cocoapods/repos/master
git pull

即可。最後進入自己的工程,在自己工程的 podFile 第一行加上:

source 'https://mirrors.tuna.tsinghua.edu.cn/git/CocoaPods/Specs.git'

然後就可以正常 pod install 了(第一次可能需要刪除已經存在的 Podfile.lock 文件)。

另外,有時候比如 git reset 到某個提交點後做 pod install 時出現

NoMethodError - undefined method `each' for nil:NilClass

的錯誤,這一般也是需要刪除 Podfile.lock 文件。

一些 Cocoapods 使用技巧

pod install 背後的原理其實就是生成了一個 ios/Pods/ 目錄,並在裏面自動放入或刪除各個第三方庫的 .h 頭文件及編譯配置文件。 .h 頭文件所在的目錄名就是相應第三方庫的 .podspec 文件中寫明的 name 字段,這樣你自己的源代碼或其它第三方庫就能簡單地以 <SomeName/some.h> 來調用該庫的功能了。

.podspec 文件中的 source 字段雖然是必須的,但只要你自己的源代碼並不打算髮布到 cocoapods 則 source 字段裏面的內容是可以瞎寫的,因爲就算你寫了個不存在的 .git 網絡鏈接, pod install 仍然會從當前硬盤中該 .podspec 文件所在路徑中軟鏈接 source_files 字段指定的 .h 頭文件到 ios/Pods/ 相應目錄中。

.podspec 文件中的 source_files 字段中的路徑必須是當前 .podspec 文件所在路徑及其子目錄,如果用 ../ 來指明上層目錄的話,雖然 pod install 時不會報錯,但實際上並沒有任何 .h 文件被軟鏈接過去導致後續編譯失敗。

如果你有自己的帶有 Headers/ 目錄的 pod 庫比如 SomeFrame.framework ,也有使用到該 framework 的自己的另一個 pod 源代碼比如 SomeSource ,而且這兩者都不打算髮布到 cocoapods ,則除了在 Podfile 中將這兩個 pod 都寫進去之外, 還需要在 SomeSource.podspec 文件中寫明 s.dependency 'SomeFrame' 語句,否則雖然 pod install 時不會報錯,但後續在編譯到 SomeSource 時會報錯說找不到 <SomeFrame/some.h> 文件。這裏也可以看到蘋果公司編譯系統一個反人類的設計(另一個反人類的是 objectC 中的方括號 [] 函數調用語法):你無法成功 #import <SomeFrame.framework/Headers/some.h> ,而只能在如上所說 s.dependency 'SomeFrame' 之後才能成功 #import <SomeFrame/some.h> ,雖然實際上硬盤裏的 some.h 並不存在於任何叫做 SomeFrame/ 的目錄中。

pod install 運行結束後可能會有一些警告提示 target overrides ,這可以參考 解決使用 CocoaPods 執行 pod install 時出現 - Use the $(inherited) flag … 警告

可以參閱 Podfile文件用法詳解 等文章。

Redux

還在糾結 Flux 或 Relay,或許 Redux 更適合你

Redux 中文文檔

npm install --save redux react-redux
npm install --save-dev redux-devtools

react-native-unimodules

react-native 興起之初,各種第三方組件百家爭鳴,但也良莠不齊。最近看來 react-native-unimodules 漸有一統之勢,它支持許多開發 APP 時用得到的方方面面的 Packages ,而且其中所謂 bare workflow 也就是不需要和 Expo 綁定的獨立 Packages 已經足夠多了。

如果是在 iOS 中使用 react-native-unimodules ,則必須要使用上面提到的 pod install 才能正常運行。

參考 moles-web

攜程基於 react-web 做了個高級版 moles-web ,現在已經在攜程的主 App 上投入生產,詳見 Moles:攜程基於React Native的跨平臺開發框架 ,只是其目前最新版還未開源,可以先拿 npm 上的舊版本與 react-web 代碼整合用用。

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