背景介绍
React Native(后续简称'RN')是最近一段时间非常火的前端跨移动端技术, 目前在Github上watch 2500+, star36000+. 国外使用这项技术的包括Facebook公司本身的Facebook和Facebook Groups, 国内使用这项技术的APP包括腾讯系的手机QQ, QQ空间, QQ音乐, 还有阿里的天猫. 阿里系在此基础上开源了自己的weex, star也有5k+.
目前已经在项目中使用了近半年的RN, 表现还算稳定. 趟了不少坑, 吃了很多亏. 将自己走过的路记录下来, 希望对大家有所帮助.
正题
按照RN官网推荐的方式安装好node, watchman等环境后, 可以在react-native init AwesomeProject
之后跑通RN的demo. 但是这样得到的工程是纯新的, 然而绝大部分情况下, 我们都是在已有的工程里加入RN, 因此, 需要在已有项目中接入RN.
PS:翻不了墙的同学可以查看此网站. 配置环境等因为墙的存在会带来一些麻烦, 这方面的文章网上很多, 就不赘述.
官方推荐的接入方式
官方推荐使用CocoaPods. 半年前曾经试过这种方式, 带来的问题是无法及时更新RN版本. 不过此时官网的RN版本是0.31, 而文档中pod已经可以安装0.26.0版本. 或许不失为一种优雅方法, 值得一试.
我推荐的接入方式
趟过的坑
刚开始在项目中引入RN的时候, 参考的是vczero的一篇文章. 将node_modules整个拷到项目目录下. 但是带来的问题是无法管理node_modules. node_modules文件夹中有数万个文件, 当时年少不懂事, 一口气将node_modules文件夹上传SVN, 却经历了无数次失败. 原因是文件数太多. 当然将这些文件分批上传是一种方法, 然而感觉十分费体力, 且万一后面要更新RN版本, 难道又要经历一次这种痛苦?
于是不打算将node_modules上传, 而是变成本地管理(即人手拷贝一份). 在经历了几天蜜月期后, 我们发现RN本身的限制(其实就是bug), 要修改RN源码. 无法使用版本管理的坏处此时体现了, 我们需要在线下维护一份修改的代码. 中间经历了两次升级RN版本, 于是一个一个对照源码进行修改. 往事不堪回首.
那么到底怎么做?
node_modules中包含两个部分代码, JS代码和原生代码(OC和Java). 实际上, 只有原生代码需要加入原生项目中编译, 而JS代码只用于打包bundle. 这样意味着, 我们可以将node_modules分成两个部分, 原生代码可以随原生项目的SVN/Git进行版本控制, 而JS部分可以通过npm的package.json进行版本控制. 这样, 原生开发同学不需要下载node_modules, 也可以对RN的源码进行修改, 而RN开发同学也可以享受版本控制的好处.
下面介绍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项目, 创建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中添加静态库文件.
如libRCTText.a等. libRCT开头的都加上.
步骤5
Build Settings添加循环依赖
在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开发.
小细节
iOS真机调试, 需要将localHost改为本机的ip, 同时手机要与电脑处于同一wifi下.
如果要真机chrome debug, 要修改RCTWebSocketExecutor.m
中setup
函数的URLString
的localHost.
Android真机调试就是adb reverse tcp:8081 tcp:8081
.
Android环境搭建一些坑可以参考我这篇文章.
网友评论