本文主要記錄了自己在往原生項目中集成React-Native(以下簡稱RN)開發的一些經驗和踩的坑,對這次的經歷做一個備忘錄,同時希望能幫到更多的人。
關于為什么要使用RN開發,本文不做更多的論述。RN的優缺點的論點網上太多了,讀者自行搜索查找、思考、甄別。
目前RN的最新版本是051,本文所有的內容都在該版本上的開發、測試。
我本人使用的是Mac端開發,并只在iOS的項目上做的測試。
好,進入正題。
一、搭建RN開發環境
既然要使用RN開發,最基本的肯定要搭建其開發環境。搭建RN開發環境一共分為:
- 安裝必要軟件
- 測試安裝
1. 安裝必需的軟件
Homebrew
Homebrew, Mac系統的包管理器,用于安裝NodeJS和一些其他必需的工具軟件。
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
在Max OS X 10.11(El Capitan)版本中,homebrew在安裝軟件時可能會碰到/usr/local
目錄不可寫的權限問題。可以使用下面的命令修復:
sudo chown -R `whoami` /usr/local
Node
使用Homebrew來安裝Node.js.
React Native目前需要NodeJS 5.0或更高版本。本文發布時Homebrew默認安裝的是最新版本,一般都滿足要求。
brew install node
安裝完node后建議設置npm鏡像以加速后面的過程(或使用科學上網工具)。注意:不要使用cnpm!cnpm安裝的模塊路徑比較奇怪,packager不能正常識別!
npm config set registry https://registry.npm.taobao.org --global
或
npm config set disturl https://npm.taobao.org/dist --global
Yarn、React Native的命令行工具(react-native-cli)
Yarn是Facebook提供的替代npm的工具,可以加速node模塊的下載。React Native的命令行工具用于執行創建、初始化、更新項目、運行打包服務(packager)等任務。
npm install -g yarn react-native-cli
安裝完yarn后同理也要設置鏡像源:
yarn config set registry https://registry.npm.taobao.org --global
或
yarn config set disturl https://npm.taobao.org/dist --global
如果你看到EACCES: permission denied
這樣的權限報錯,那么請參照上文的homebrew譯注,修復/usr/local
目錄的所有權:
sudo chown -R `whoami` /usr/local
安裝完yarn之后就可以用yarn代替npm了,例如用yarn
代替npm install
命令,用yarn add 某第三方庫名
代替npm install --save 某第三方庫名
。
Watchman
Watchman是由Facebook提供的監視文件系統變更的工具。安裝此工具可以提高開發時的性能(packager可以快速捕捉文件的變化從而實現實時刷新)。
brew install watchman
Xcode
這個就不多說了,在APPStrore下載即可。最好保證下載Xcode7.0以上。
2.測試
以上軟件安裝好了之后,我們現在可以開始嘗試創建一個RN項目了,測試看是否出現紕漏。
打開Mac的終端工具命令行:
react-native init myFirstRNProject
這里是在mac的根目錄創建一個myFirstRNProject的文件夾。我們的項目所需要的一切文件也會在這個文件夾里面被創建好。這種方式創建的就是最新版本的RN,也就是0.51版本。
如果我們需要進行指定版本的創建的話,可以像下面這樣創建:
react-native init myFirstRNProject --version 0.45
這種方式將會創建0.45版本的RN項目。
創建RN文件夾后,執行:
cd myFirstRNProject
進入到該項目中。
react-native run-ios
啟動項目中的iOS部分。
注意: 啟動之后,Mac會自動開啟一個終端的對話框,這個對話框在項目的開啟期間必須要一直打開著,如果被關閉,整個項目也就被關閉了。
打開項目看到這個樣子:
我們將在
APP.JS
文件夾中編寫項目需要的代碼。 如果是049之前的版本,則應該在 index.ios.js
和index.Android.js
中分別iOS和安卓的代碼。如果一切正常,說明項目就是創建成功了。
二、搭建原生項目集成環境
搭建好了開發環境之后,我們能夠隨時創建一個新的項目了。這時候就具備了給原生項目集成RN的環境。
1. 首先創建一個空的文件夾。
這個文件夾將會是集成之后項目文件。假設我給他取名: iOS-RN.
2. 在 iOS-RN 文件夾中,創建一個/ios文件。
這個/ios文件中將存放原生項目中所有的文件。這直接將原生項目中的文件復制一份拷貝過來即可。
3. 安裝JavaScript依賴包: package.js文件
在項目根目錄(和/ios平級)下創建一個名為package.json的空文本文件,然后填入以下內容:
{
"name": "MyReactNativeApp",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node node_modules/react-native/local-cli/cli.js start"
},
"dependencies": {
"react": "16.0.0-alpha.6", // 指定了React 版本
"react-native": "0.51" //這里指定了RN的版本
}
}
示例中的version字段沒有太大意義(除非你要把你的項目發布到npm倉庫)。scripts中是用于啟動packager服務的命令。dependencies中的react和react-native的版本取決于你的具體需求。一般來說我們推薦使用最新版本。你可以使用npm info react和npm info react-native來查看當前的最新版本。另外,react-native對react的版本有嚴格要求,高于或低于某個范圍都不可以。本文無法在這里列出所有react native和對應的react版本要求,只能提醒讀者先嘗試執行npm install,然后注意觀察安裝過程中的報錯信息,例如require react@某.某.某版本, but none was installed,然后根據這樣的提示,執行npm i -S react@某.某.某版本。如果你使用多個第三方依賴,可能這些第三方各自要求的react版本有所沖突,此時應優先滿足react-native所需要的react版本。其他第三方能用則用,不能用則只能考慮選擇其他庫。
設置完成之后,安裝依賴包:
$ npm install
4. 在原生項目中使用CocoaPod添加RN依賴文件
使用終端cd
進入到/ios文件中,安裝CocoaPod依賴包管理系統。(這里推薦使用CocoaPods,如果之前的原生項目中沒有安裝的話,需要自行想辦法安裝一個)。
對于已經安裝了CocoaPod 的項目,我們進入到對應的podfile
文件:
$ vim podfile
在podfile文件中添加以下內容:
# 'node_modules'目錄一般位于根目錄中
# 但是如果你的結構不同,那你就要根據實際路徑修改下面的`:path`
pod 'React', :path => '../node_modules/react-native', :subspecs => [
'Core',
'CxxBridge', # 如果RN版本 >= 0.45則加入此行
'DevSupport', # 如果RN版本 >= 0.43,則需要加入此行才能開啟開發者菜單
'RCTText',
'RCTNetwork',
'RCTWebSocket', # 這個模塊是用于調試功能的
# 在這里繼續添加你所需要的RN模塊
]
# 如果你的RN版本 >= 0.42.0,則加入下面這行。
pod "yoga", :path => "../node_modules/react-native/ReactCommon/yoga"
# 這里注意: 如果是0.49以下的RN,則使用下面這條:
# pod "Yoga", :path => "../node_modules/react-native/ReactCommon/yoga"
# 如果RN版本 >= 0.45則加入下面三個第三方編譯依賴
pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec'
pod 'GLog', :podspec => '../node_modules/react-native/third-party-podspecs/GLog.podspec'
pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec'
完了之后,更新Pod。
$ pod install
有時候會更新失敗,注意查看失敗的原因,對癥修改即可。
更新成功之后,我們在項目中就可以通過import React
使用React提供的庫文件了。在每一個需要用到RN相關內容的界面的原生代碼中,都需要加入這個頭文件。
三、橋接RN和iOS項目中的內容
按照傳統,我打算使用RN寫一個“Heollo world” 的界面,然后在原生的項目中使用這個界面。
1. 創建index.js文件。
在和ios文件夾平級的目錄下(根目錄),使用命令
$ touch index.js
創建index.js文件。這個文件是RN的入口文件,如果是 049之前的RN,那么應該創建index.ios.js文件。
2. 在index.js文件寫入以下代碼:
import React from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View
} from 'react-native';
class FirstView extends React.Component {
render() {
var contents = this.props.rootTag;
return (
<View style={styles.center}>
<Text >
{this.props.content}
</Text>
</View>
);
}
}
const styles = StyleSheet.create({
center: {
marginTop: 50,
width:120,
height: 60,
justifyContent: 'center',
alignItems: 'center',
backgroundColor:"red"
},
});
// 整體js模塊的名稱
AppRegistry.registerComponent('FirstView', () => FirstView);
具體代碼的意思就是在一個頁面中添加了一個包含“Hello world”文字的 <Text>控件。
3. 編寫原生代碼對接RN
為了簡單起見,我直接在AppDelegate文件中,將window的根視圖設置成RN編寫的“Hello world”界面。
當然,我們同樣可以在其他的原生界面進行跳轉到RN界面。
首先
import React
然后在 didFinishLaunchingWithOptions 函數中:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
self.window = UIWindow.init(frame: CGRect.init(x: 0, y: 0, width: ScreenWidth, height: ScreenHeight))
self.window?.makeKeyAndVisible()
// 如果是 使用真機調試,需要使用電腦的IP地址。
// let url = URL.init(with: "http://192.168.0.174:8081/index.bundle?platform=ios")
// 如果是使用Xcode自帶的模擬器,則直接使用本地服務器的端口即可。
let url = URL.init(with: "http://localhost:8081/index.bundle?platform=ios")
let rootView = RCTRootView.init(bundleURL: url, moduleName: "FirstView", initialProperties: [ "content":"Hello world"], launchOptions: nil)
let VC = UIViewController.init()
VC.view = rootView
self.window?.rootViewController = VC
return true
}
注意: 這里的FirstView 的名稱必須和RN中注冊的名稱一模一樣。不然會無法識別的。
這段代碼的意思就是從RN中加載一個頁面(這個頁面就是我們寫的“Hello world”頁面),然后作為window的根視圖展示。
4. 啟動RN項目
使用mac的終端工具,cd
進入到項目的根目錄,就是上面說的 iOS-RN
文件夾,在這里可以看到 index.js
文件。
輸入命令行:
$ npm start
之后,RN項目開始啟動,最后, 終端框中會看到這句提示:Loading dependency graph, done.
,說明RN啟動完成。這時候注意,不要關閉這個終端,如果需要使用終端執行其他的命令,可以新建窗口。
這時候所有的RN依賴庫都加載完畢,等待原生項目啟動調用。
5. 啟動原生項目
Xocde中,選擇模擬器,comand+R。
如果一切正常的話,打開模擬器之后,會直接進入到了“Hello world”界面。
下圖:
以上就是在原生項目中集成RN的全部過程了。當然這個過程的步驟很多,很有可能出現各種各樣的錯誤,這時候需要耐心仔細看錯誤提示。RN的錯誤提示做的還是很成熟的,我自己接入RN以來各種錯誤大部分都是通過其錯誤提示修復的,實在不行,就上各種搜索引擎上去搜索吧。