背景介紹
React Native(后續(xù)簡稱'RN')是最近一段時間非逞⑸ィ火的前端跨移動端技術, 目前在Github上watch 2500+, star36000+. 國外使用這項技術的包括Facebook公司本身的Facebook和Facebook Groups, 國內使用這項技術的APP包括騰訊系的手機QQ, QQ空間, QQ音樂, 還有阿里的天貓. 阿里系在此基礎上開源了自己的weex, star也有5k+.
目前已經在項目中使用了近半年的RN, 表現還算穩(wěn)定. 趟了不少坑, 吃了很多虧. 將自己走過的路記錄下來, 希望對大家有所幫助.
正題
按照RN官網推薦的方式安裝好node, watchman等環(huán)境后, 可以在react-native init AwesomeProject
之后跑通RN的demo. 但是這樣得到的工程是純新的, 然而絕大部分情況下, 我們都是在已有的工程里加入RN, 因此, 需要在已有項目中接入RN.
PS:翻不了墻的同學可以查看此網站. 配置環(huán)境等因為墻的存在會帶來一些麻煩, 這方面的文章網上很多, 就不贅述.
官方推薦的接入方式
官方推薦使用CocoaPods. 半年前曾經試過這種方式, 帶來的問題是無法及時更新RN版本. 不過此時官網的RN版本是0.31, 而文檔中pod已經可以安裝0.26.0版本. 或許不失為一種優(yōu)雅方法, 值得一試.
我推薦的接入方式
趟過的坑
剛開始在項目中引入RN的時候, 參考的是vczero的一篇文章. 將node_modules整個拷到項目目錄下. 但是帶來的問題是無法管理node_modules. node_modules文件夾中有數萬個文件, 當時年少不懂事, 一口氣將node_modules文件夾上傳SVN, 卻經歷了無數次失敗. 原因是文件數太多. 當然將這些文件分批上傳是一種方法, 然而感覺十分費體力, 且萬一后面要更新RN版本, 難道又要經歷一次這種痛苦?
于是不打算將node_modules上傳, 而是變成本地管理(即人手拷貝一份). 在經歷了幾天蜜月期后, 我們發(fā)現RN本身的限制(其實就是bug), 要修改RN源碼. 無法使用版本管理的壞處此時體現了, 我們需要在線下維護一份修改的代碼. 中間經歷了兩次升級RN版本, 于是一個一個對照源碼進行修改. 往事不堪回首.
那么到底怎么做?
node_modules中包含兩個部分代碼, JS代碼和原生代碼(OC和Java). 實際上, 只有原生代碼需要加入原生項目中編譯, 而JS代碼只用于打包bundle. 這樣意味著, 我們可以將node_modules分成兩個部分, 原生代碼可以隨原生項目的SVN/Git進行版本控制, 而JS部分可以通過npm的package.json進行版本控制. 這樣, 原生開發(fā)同學不需要下載node_modules, 也可以對RN的源碼進行修改, 而RN開發(fā)同學也可以享受版本控制的好處.
下面介紹Mac-iOS下的具體步驟:
步驟1
獲取你所需要的RN版本(node_modules).
如在命令行輸入react-native init AwesomeProject
, 得到最新版的RN. 獲取AwesomeProject中的package.json和node_modules. 將二者置于與原生項目文件夾平級的地方. 即與iOS和Android文件夾平級之處, 方便雙平臺使用.
步驟2
拷貝node_modules/react-native文件夾至原生項目中, iOS項目保留Libraries文件夾和React文件夾(安卓項目保留ReactAndroid文件夾). 其余所有刪除.
步驟3
iOS項目, 創(chuàng)建Group,放置RN工程項目:
/node_modules/react-native/React/React.xcodeproj
/node_modules/react-native/Libraries/Text/RCTText.xcodeproj
.
.
.
/node_modules/react-native/Libraries/WebSocket/RCT WebSocket.xcodeproj
你需要用到哪些就加哪些. 全部加上也無妨.
步驟4
Build Rules中添加靜態(tài)庫文件.
如libRCTText.a等. libRCT開頭的都加上.
步驟5
Build Settings添加循環(huán)依賴
在Targets-Build Settings-Header Search Paths中加入$(PROJECT_DIR)/項目名/ReactNative/react-native/React
這里要加入的是react-native/React
文件夾的路徑, 我的react-native文件夾位于項目名/ReactNative
下,因此是這樣寫.
步驟6
設置Other Linker Flags
Targets-Build Settings-Other Linker Flags中加入-ObjC
步驟7
刪除原生項目中步驟2拷貝過來的react-native文件夾中所有JS文件. 這步本可以和步驟2合為1步,單獨列出的原因是: 如果沒有刪除其中的JS文件, 其中的JS代碼@providesModule
provide了很多Module, 會與你在步驟1中的node_modules中的代碼沖突.
步驟8
刪除啟動node服務腳本.
打開步驟3中引入的RN工程項目:React.xcodeproj-Targets-Build Phases-Run Script. 刪除啟動node服務腳本的那個腳本. 即內容是if nc -w 5 -z localhost 8081 ; then if ! curl -s "http://localhost:8081/status" | grep -q "packager-status:running" ; then echo "Port 8081 already in use, packager is either not running or not running correctly" exit 2 fi else open "$SRCROOT/../packager/launchPackager.command" || echo "Can't start packager automatically" fi
的腳本
步驟9
隨原生項目上傳react-native文件夾, 此時react-native文件夾中只有原生代碼, 可以進行版本控制;
修改package.json, 修改你需要的內容(如修改dependencies, 將某些組件固定在某個版本), 之后用package.json控制更新node_modules.
package.json也上傳SVN, 大家共用這個管理node_modules.
步驟10
打開命令行, 進入與項目平級的目錄(即node_modules所在目錄), 輸入npm start. 啟動node服務.
打開XCode/Android Studio, 進入RN開發(fā).
小細節(jié)
iOS真機調試, 需要將localHost改為本機的ip, 同時手機要與電腦處于同一wifi下.
如果要真機chrome debug, 要修改RCTWebSocketExecutor.m
中setup
函數的URLString
的localHost.
Android真機調試就是adb reverse tcp:8081 tcp:8081
.
Android環(huán)境搭建一些坑可以參考我這篇文章.