出于公司需求,需要再已经运行了5年的项目中添加react native .看到网上基本上就是照抄RN中文网的, 时间也很久了, 把自己集成的过程记录下,尝试总结下 ,希望帮助需要的人吧。
1.RN环境
我们的开发电脑安装RN的环境, 这里就不多做介绍了,RN中文网写的很详细。
2. 安装 JavaScript 依赖包
在项目根目录下创建一个名为package.json的空文本文件,填入内容,填入什么内容呢?
其实你可以使用react-native init 项目名
命令创建一个纯RN项目,然后去参考其ios目录中的package.json 和 Podfile文件【备注:RN的最新版本0.6+开始使用cocopods管理ios项目,并管理ios和RN的项目依赖】
这里简单贴一下示例:
package.json
{
"name": "myRactNative",
"version": "0.0.1",
"private": true,
"scripts": {
"android": "react-native run-android",
"ios": "react-native run-ios",
"start": "react-native start",
"test": "jest",
"lint": "eslint ."
},
"dependencies": {
"react": "16.9.0",
"react-native": "0.61.5"
},
"devDependencies": {
"@babel/core": "^7.8.7",
"@babel/runtime": "^7.8.7",
"@react-native-community/eslint-config": "^0.0.7",
"babel-jest": "^25.1.0",
"eslint": "^6.8.0",
"jest": "^25.1.0",
"metro-react-native-babel-preset": "^0.58.0",
"react-test-renderer": "16.9.0"
},
"jest": {
"preset": "react-native"
}
}
然后运行yarn add react-native
这样默认会安装最新版本的 React Native,同时会打印出类似下面的警告信息(你可能需要滚动屏幕才能注意到):
warning "react-native@0.52.2" has unmet peer dependency "react@16.2.0".
这是正常现象,意味着我们还需要安装指定版本的 React:
yarn add react@16.2.0
注意必须严格匹配警告信息中所列出的版本,高了或者低了都不可以。
如果你使用多个第三方依赖,可能这些第三方各自要求的 react 版本有所冲突,此时应优先满足react-native所需要的react版本。其他第三方能用则用,不能用则只能考虑选择其他库。
3. 安装 Cocopods 依赖包
Podfile
platform :ios, '9.0'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
target 'myRactNative' do
# Pods for myRactNative
pod 'FBLazyVector', :path => "../node_modules/react-native/Libraries/FBLazyVector"
pod 'FBReactNativeSpec', :path => "../node_modules/react-native/Libraries/FBReactNativeSpec"
pod 'RCTRequired', :path => "../node_modules/react-native/Libraries/RCTRequired"
pod 'RCTTypeSafety', :path => "../node_modules/react-native/Libraries/TypeSafety"
pod 'React', :path => '../node_modules/react-native/'
pod 'React-Core', :path => '../node_modules/react-native/'
pod 'React-CoreModules', :path => '../node_modules/react-native/React/CoreModules'
pod 'React-Core/DevSupport', :path => '../node_modules/react-native/'
pod 'React-RCTActionSheet', :path => '../node_modules/react-native/Libraries/ActionSheetIOS'
pod 'React-RCTAnimation', :path => '../node_modules/react-native/Libraries/NativeAnimation'
pod 'React-RCTBlob', :path => '../node_modules/react-native/Libraries/Blob'
pod 'React-RCTImage', :path => '../node_modules/react-native/Libraries/Image'
pod 'React-RCTLinking', :path => '../node_modules/react-native/Libraries/LinkingIOS'
pod 'React-RCTNetwork', :path => '../node_modules/react-native/Libraries/Network'
pod 'React-RCTSettings', :path => '../node_modules/react-native/Libraries/Settings'
pod 'React-RCTText', :path => '../node_modules/react-native/Libraries/Text'
pod 'React-RCTVibration', :path => '../node_modules/react-native/Libraries/Vibration'
pod 'React-Core/RCTWebSocket', :path => '../node_modules/react-native/'
pod 'React-cxxreact', :path => '../node_modules/react-native/ReactCommon/cxxreact'
pod 'React-jsi', :path => '../node_modules/react-native/ReactCommon/jsi'
pod 'React-jsiexecutor', :path => '../node_modules/react-native/ReactCommon/jsiexecutor'
pod 'React-jsinspector', :path => '../node_modules/react-native/ReactCommon/jsinspector'
pod 'ReactCommon/jscallinvoker', :path => "../node_modules/react-native/ReactCommon"
pod 'ReactCommon/turbomodule/core', :path => "../node_modules/react-native/ReactCommon"
pod 'Yoga', :path => '../node_modules/react-native/ReactCommon/yoga'
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'
target 'myRactNativeTests' do
inherit! :search_paths
# Pods for testing
end
use_native_modules!
end
target 'myRactNative-tvOS' do
# Pods for myRactNative-tvOS
target 'myRactNative-tvOSTests' do
inherit! :search_paths
# Pods for testing
end
end
这里需要注意两点
【1】Podfile 文件中,node_modules 目录一般位于根目录中 但是如果你的结构不同,那你就要根据实际路径修改下面的:path =>
我贴一下我示例项目中的目录结构
截屏2020-03-1010.51.01.png
【2】Podfile 文件中,platform :ios, '9.0'
这个要注意 一定最低是9.0 否则pod instal的时候会出现类似Folly
glog
DoubleConversion
安装不上,包错误❌的问题。可以试一下。
剩下的就是 pod install
了,如果这个过程不出错,恭喜你!!已经基本完成了项目集成RN的工作~
其实说白了 就两大步, 搞定package.json
和 Podfile
剩下的就是在根目录中新建一个index.js
的RN入口文件,和在OC中调用进入RN场景的代码了,这里简单贴一下代码:
index.js
/**
* @format
*/
import {AppRegistry} from 'react-native';
import App from './App';
import {name as appName} from './app.json';
AppRegistry.registerComponent(appName, () => App);
native view -> 跳转RN
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "AppDelegate.h"
#import <React/RCTBridge.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
moduleName:@"myRactNative"
initialProperties:nil];
rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIViewController *rootViewController = [UIViewController new];
rootViewController.view = rootView;
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
return YES;
}
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#if DEBUG
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
#else
return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
#endif
}
@end
4. 下面我说下 我项目中遇到的坑
【1】Pods/boost-for-react-native/boost/compatibility/cpp_c_headers/cstdlib:11:11: error: no member named 'abort' in the global namespace
解决办法: Xcode: cstdlib no member named “xxx” in the global namespace
最后的最后, 我兴奋的运行了起来, 完美 perfect !成功了耶,于是打包测试, WC,跳转到RN界面 居然 闪退了!!!
嘚吧了那么多,其实还有一小点需要我们注意,这个是原项目集成RN中容易忽略的点,
先解释一下吧,
其实在release 环境下打包 代码中有这样一句
return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
那么这个main.jsbundle
怎么生成呢,我也网上找了rn代码打包成bundle的命令 , 什么使用curl命令生成 main.jsbundle
还有什么react-native bundle --entry-file index.ios.js --bundle-output ./bundle/ios/index.ios.jsbundle --platform ios --assets-dest ./bundle/ios --dev false
我都试一试了,反正在我这边都不行, 打包后一跳转RN界面就会闪退,
其实在RN中文网集成到现有项目
中一段未翻译的英文标注
When moving your app to production, the NSURL can point to a pre-bundled file on disk via something like [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];. You can use the react-native-xcode.sh script in node_modules/react-native/scripts/ to generate that pre-bundled file.
就是这个 react-native-xcode.sh script
脚本
这个 react-native-xcode.sh script
脚本 添加到 你项目中
就是这个Bundle React Native code and images
内容如下:
export NODE_BINARY=node
../node_modules/react-native/scripts/react-native-xcode.sh
截屏2020-03-1011.29.34.png
注意路径哦,个别项目可能不同
~ 另外 我的项目 刚集成了 RN 的热更库 微软的 code-push 有时间写也一下集成历程...
到此真正的结束了,你可以愉快的 codeing rn 代码了...
网友评论