本文主要记录了自己在往原生项目中集成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以来各种错误大部分都是通过其错误提示修复的,实在不行,就上各种搜索引擎上去搜索吧。