React-Native在iOS工程的集成
当我们想在现有的iOS开发工程中加入React-Native这个模块的时候,我们需要做一些准备工作。<我假设已经安装了homebrew>安装需要的工具:npm
一般来说只要有这个就可以,但是鉴于npm 每次都要npm install React-Native并且时间很慢,我们可以辅助使用Yarn,这个工具也是Facebook出品的,这个打React-Native的效率比
npm install
高很多。
安装好了npm之后,我们创建一个package.json文件,内容如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
{
"name" : "honer" ,
"version" : "0.0.1" ,
"private" : true ,
"scripts" : {
"update" : "echo '{\"presets\":[\"react-native\"],\"plugins\":[\"transform-decorators-legacy\",[\"react-native-css-class\",{\"pragma\":\"CSS\"}]]}' > .babelrc && mkdir bundle && npm i" ,
"start" : "node node_modules/react-native/local-cli/cli.js start" ,
"build" : "rm -rf ./bundle/* && react-native bundle --platform ios --entry-file ./ReactComponent/index.ios.js --bundle-output ./bundle/main.jsbundle --assets-dest ./bundle/ --dev false" ,
"test" : "jest"
},
"dependencies" : {
"react" : "15.3.2" ,
"react-native" : "0.36.1"
},
"jest" : {
"preset" : "jest-react-native"
},
"devDependencies" : {
"babel-jest" : "16.0.0" ,
"babel-plugin-react-native-css-class" : "git+https://github.com/qq4647805/babel-plugin-react-native-css-class.git" ,
"babel-plugin-transform-decorators-legacy" : "^1.3.4" ,
"babel-plugin-transform-runtime" : "^6.15.0" ,
"babel-preset-react-native" : "1.9.0" ,
"jest" : "16.0.2" ,
"jest-react-native" : "16.1.0" ,
"react-test-renderer" : "15.3.2"
}
}
通过终端进入工程根目录下,如果这时安装了Yarn。在终端输入
yarn
,回车一按,自动查找需要安装的packages
1
2
3
4
5
6
7
8
9
10
11
RickdeMacBook-Pro:xueba_ios_ 2016 Wenba$ yarn
yarn install v 0.16 . 1
info No lockfile found.
[ 1 / 4 ] 🔍 Resolving packages...
warning jest > jest-cli > istanbul-api > fileset > minimatch@ 2.0 . 10 : Please update to minimatch 3.0 . 2 or higher to avoid a RegExp DoS issue
[ 2 / 4 ] 🚚 Fetching packages...
[ 3 / 4 ] 🔗 Linking dependencies...
warning Unmet peer dependency "whatwg-fetch@^1.0.0" .
[ 4 / 4 ] 📃 Building fresh packages...
success Saved lockfile.
✨ Done in 19.62 s.
如果没有安装Yarn,安装了npm的话,只要键入 npm install 就会安装packages
然后我们去修改iOS工程的podfile文件,在所在的target多增加这个pod
1
2
3
4
5
6
7
8
pod 'React' , :path => './node_modules/react-native' , :subspecs => [
'Core' ,
'RCTImage' ,
'RCTNetwork' ,
'RCTText' ,
'RCTWebSocket' ,
# Add any other subspecs you want to use in your project
]
在iOS工程目录下执行
Pod install
。等待安装完成。此时React-Native模块已经加入到我们iOS的工程里了。
在iOS工程使用React-Native。
在工程新建一个ReactView。用于展示React-Native
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
@implementation ReactView
- ( instancetype ) initWithFrame: ( CGRect ) frame {
self = [ super initWithFrame: frame ];
if ( self ) {
NSURL * jsCodeLocation = [[ NSBundle mainBundle ] URLForResource: @"bundle/main" withExtension: @"jsbundle" ];
/*
For production use, this `NSURL` could instead point to a pre-bundled file on disk:
NSURL *jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
To generate that file, run the curl command and add the output to your main Xcode build target:
curl http://localhost:8081/index.ios.bundle -o main.jsbundle
*/
_rootView = [[ RCTRootView alloc ] initWithBundleURL: jsCodeLocation moduleName: @"honer" initialProperties: nil launchOptions: nil ];
[ self addSubview: _rootView ];
}
return self ;
}
- ( void ) layoutSubviews {
[ super layoutSubviews ];
_rootView . frame = self . bounds ;
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code
}
*/ ``
@end
在终端输入
(JS_DIR=`pwd`/ReactComponent;cd node_modules/react-native; npm run start -- --root $JS_DIR)
启动React-Native服务
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
RickdeMacBook - Pro: BestNote Wenba$ ( JS_DIR = ` pwd ` / ReactComponent ; cd node_modules / react - native ; npm run start -- -- root $JS_DIR )
> react - native @ 0.36.1 start / Users / Rick / Documents / Work / ChatDemo / ReactNative / BestNote / node_modules / react - native
> / usr / bin / env bash - c ' . / packager / packager . sh "$@" || true ' -- "--root" "/Users/Rick/Documents/Work/ChatDemo/ReactNative/BestNote/ReactComponent"
( node: 14754 ) DeprecationWarning: os . tmpDir () is deprecated . Use os . tmpdir () instead .
( node: 14754 ) DeprecationWarning: Using Buffer without ` new ` will soon stop working . Use ` new Buffer () ` , or preferably ` Buffer . from () ` , ` Buffer . allocUnsafe () ` or ` Buffer . alloc () ` instead .
Scanning 717 folders for symlinks in / Users / Rick / Documents / Work / ChatDemo / ReactNative / BestNote / node_modules ( 9 ms )
┌────────────────────────────────────────────────────────────────────────────┐
│ Running packager on port 8081. │
│ │
│ Keep this packager running while developing on any JS projects . Feel │
│ free to close this tab and run your own packager instance if you │
│ prefer . │
│ │
│ https: //github.com/facebook/react-native │
│ │
└────────────────────────────────────────────────────────────────────────────┘
Looking for JS files in
/ Users / Rick / Documents / Work / ChatDemo / ReactNative / BestNote
/ Users / Rick / Documents / Work / ChatDemo / ReactNative / BestNote / ReactComponent
[ Hot Module Replacement ] Server listening on / hot
React packager ready .
[ 11 / 15 / 2016 , 1 : 50 : 38 PM ] < START > Initializing Packager
[ 11 / 15 / 2016 , 1 : 50 : 38 PM ] < START > Building in - memory fs for JavaScript
[ 11 / 15 / 2016 , 1 : 50 : 38 PM ] < END > Building in - memory fs for JavaScript ( 173 ms )
[ 11 / 15 / 2016 , 1 : 50 : 38 PM ] < START > Building Haste Map
[ 11 / 15 / 2016 , 1 : 50 : 39 PM ] < END > Building Haste Map ( 124 ms )
[ 11 / 15 / 2016 , 1 : 50 : 39 PM ] < END > Initializing Packager ( 365 ms )
[ 11 / 15 / 2016 , 1 : 50 : 42 PM ] < START > Requesting bundle: { "url" : "/index.ios.bundle?platform=ios" }
[ 11 / 15 / 2016 , 1 : 50 : 42 PM ] < START > Transforming modules
transformed 662 / 662 ( 100 % )
NSURL *jsCodeLocation = [NSURL URLWithString:@"http://10.88.1.90:8081/index.ios.bundle?platform=ios"];
这个IP是开启服务的电脑IP。
(JS_DIR=`pwd`/ReactComponent;cd node_modules/react-native; npm run start -- --root $JS_DIR)
定义的JSDir会在这两个目录下去查找js文件
1
2
/ Users / Rick / Documents / Work / ChatDemo / ReactNative / BestNote
/ Users / Rick / Documents / Work / ChatDemo / ReactNative / BestNote / ReactComponent
我们在
ReactComponent
这个目录下放入index.ios.js文件。文件内容如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import React , { Component } from 'react'
import {
AppRegistry ,
Text
} from 'react-native' ;
import Main from './src/main.js'
class myhonor extends Component {
render () {
return (
< Main >< /Main>
);
}
}
AppRegistry . registerComponent ( 'honer' , () => myhonor );
在这里注册组件honer,我们在ReactView类中找到这个honer模块去使用。
此时我们运行我们的工程会发现运行ok的
离线包
加载需要时间,此时页面是空白,不好,建议将资源以及页面都打包成离线包,这样不用每次都连网去请求页面。如果有新的页面更换,可以先加载旧的页面,在渲染成新页面。
我们在终端输入
1
2
3
4
5
6
react - native bundle \
-- platform ios \
-- entry - file index . ios2 . js \
-- bundle - output . / main . jsbundle \
-- assets - dest . / \
-- dev true
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
RickdeMacBook - Pro : BestNote Wenba$ react - native bundle -- platform ios -- dev false -- entry - file . / ReactComponent / index . ios . js -- bundle - output main . jsbundle -- assets - dest . / Bundle
( node : 16763 ) DeprecationWarning : os . tmpDir () is deprecated . Use os . tmpdir () instead .
( node : 16763 ) DeprecationWarning : Using Buffer without ` new ` will soon stop working . Use ` new Buffer () ` , or preferably ` Buffer . from () ` , ` Buffer . allocUnsafe () ` or ` Buffer . alloc () ` instead .
[ 11 / 15 / 2016 , 2 : 28 : 17 PM ] < START > Initializing Packager
[ 11 / 15 / 2016 , 2 : 28 : 17 PM ] < START > Building in - memory fs for JavaScript
[ 11 / 15 / 2016 , 2 : 28 : 17 PM ] < END > Building in - memory fs for JavaScript ( 165 ms )
[ 11 / 15 / 2016 , 2 : 28 : 17 PM ] < START > Building Haste Map
[ 11 / 15 / 2016 , 2 : 28 : 17 PM ] < END > Building Haste Map ( 226 ms )
[ 11 / 15 / 2016 , 2 : 28 : 17 PM ] < END > Initializing Packager ( 463 ms )
[ 11 / 15 / 2016 , 2 : 28 : 17 PM ] < START > Transforming modules
[ 11 / 15 / 2016 , 2 : 28 : 25 PM ] < END > Transforming modules ( 7758 ms )
bundle : start
bundle : finish
bundle : Writing bundle output to : main . jsbundle
bundle : Done writing bundle output
bundle : Copying 15 asset files
bundle : Done copying assets
将我们的js文件打包成bundle,同事将资源文件也打包起来,如果–assets-dest ./ 这个参数不加,会导致我们页面的img图片资源缺失。这个有点坑。
我假设已经安装了homebrew>