首先瀑焦,講React Native的發(fā)布更新,這就涉及到React Native的熱更新主要是怎么工作的浪耘,關(guān)鍵在于bundle的更新竿报。我們先來(lái)看看ReactNative是怎么處理bundle文件(bundle文件用于資源管理)的「任可以有如下兩種方式:1鹃唯、app發(fā)版時(shí),將bundle文件內(nèi)置到app中瓣喊,同時(shí)將圖片和js文件內(nèi)置到app中(Android和iOS處理的不同)2坡慌、app在合適的時(shí)機(jī),加載服務(wù)端最新的bundle文件
下面一張流程圖簡(jiǎn)單介紹ReactNative的熱更新機(jī)制:(參考自:http://blog.csdn.net/codetomylaw/article/details/52115704)
一藻三、打離線包(打包bundle文件內(nèi)置到app中)
離線包即本地存著一個(gè)離線包洪橘,保證沒(méi)有網(wǎng)絡(luò)的時(shí)候程序不會(huì)報(bào)錯(cuò)。1棵帽、將js代碼打包到j(luò)sbundle文件中熄求。在index.ios.js所在目錄下,執(zhí)行以下命令(文件名自定義逗概,使用codepush的時(shí)候最好命名為默認(rèn)的main.jsbundle):
// 無(wú)圖片資源等react-native bundle --entry-file index.ios.js --platform ios --bundle-output main.jsbundle// 有圖片資源react-native bundle --entry-file index.ios.js --platform ios --bundle-output index.ios.bundle --platform ios --dev false --assets-dest ./ // 或者放bundle文件夾里(注意要先保證bundle文件夾存在5芡怼!!) react-native bundle –entry-file index.ios.js –bundle-output ./bundle/iosBundle/index.ios.jsbundle –platform ios –assets-dest ./bundle/iosBundle –dev false /entry-file: RN的入口文件bundle-out: 輸出bundle文件的輸出路徑(bundle文件名和oc里面的代碼要對(duì)應(yīng))asset-dest:輸出的asset資源目錄/
2卿城、添加到項(xiàng)目中枚钓。在xcode中添加assets【必須用Create folder references的方式,添加完是藍(lán)色文件夾圖標(biāo)】和index.ios.jsbundle(或者main.jsbundle瑟押、命名不同)
網(wǎng)上參考的放bundle文件夾的目錄結(jié)構(gòu)和項(xiàng)目結(jié)構(gòu)如下:
參考自:https://segmentfault.com/a/1190000004189538
個(gè)人利用第一句命令創(chuàng)建的包搀捷,目錄如下:
離線包目錄結(jié)構(gòu).png
3、修改AppDelegate.m文件(只使用離線包不使用熱更新的情況)
// URLForResource根據(jù)第一步對(duì)應(yīng)的名字對(duì)應(yīng)修改jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"index.ios" withExtension:@"jsbundle"];
4多望、模擬器或者真機(jī)調(diào)試都沒(méi)有問(wèn)題嫩舟。
順帶列舉下ios打包可能遇到的問(wèn)題(雖然我都沒(méi)遇到哈):1)離線包如果開(kāi)啟了chrome調(diào)試,會(huì)訪問(wèn)調(diào)試服務(wù)器怀偷,而且會(huì)一直loading出不來(lái)家厌。2)如果bundle的名字是main.jsbundle,app會(huì)一直讀取舊的,改名就好了。枢纠。像街。非常奇葩的問(wèn)題,我重新刪了app晋渺,clean工程都沒(méi)用镰绎,就是不能用main.jsbundle這個(gè)名字。3)必須用Create folder references【藍(lán)色文件夾圖標(biāo)】的方式引入圖片的assets木西,否則引用不到圖片4)執(zhí)行bundle命令之前畴栖,要保證相關(guān)的文件夾都存在
二、使用CodePush實(shí)現(xiàn)熱更新
- 環(huán)境準(zhǔn)備(Mac)
1)安裝Code-push cli
$ npm install -g code-push-cli
2) 注冊(cè)CodePush賬戶
$ code-push register
執(zhí)行以上命令將會(huì)自動(dòng)打開(kāi)如下圖所示的注冊(cè)頁(yè)面:
注冊(cè)頁(yè)面.png
可以使用github或者M(jìn)icrosoft帳戶注冊(cè)(本文使用GitHub賬戶進(jìn)行注冊(cè))八千,注冊(cè)成功后將會(huì)生成如下圖所示相應(yīng)的access token:
access token.png
按照提示在終端輸入剛生成的access token(會(huì)自動(dòng)登錄):
[圖片上傳中吗讶。。恋捆。(6)]輸入access token.png
3)添加CodePush應(yīng)用
$ code-push app add XXX //xxx 為你要熱部署的app name
結(jié)果如下:
[圖片上傳中照皆。。沸停。(7)]添加CodePush應(yīng)用.png
- 安裝CodePush
在項(xiàng)目更目錄(或者說(shuō)package.json所在目錄)執(zhí)行以下語(yǔ)句安裝CodePush膜毁,會(huì)自動(dòng)對(duì)應(yīng)修改package.json內(nèi)容。
npm install --save react-native-code-push
效果如下:
安裝CodePush.png
- 集成code-push 到工程文件
CodePush集成到項(xiàng)目中愤钾,一般有三種方法:RNPM瘟滨、CocoaPods 、"Manual"
詳細(xì)可參考CodePush的Github:https://github.com/Microsoft/react-native-code-push
下文分別對(duì)其接入方法進(jìn)行簡(jiǎn)單介紹:個(gè)人感覺(jué)按情況分能颁,如果是將React Native集成到原生項(xiàng)目中的項(xiàng)目杂瘸,因?yàn)楸旧響?yīng)該有用到cocoaPods,所以推薦使用cocoaPods接入伙菊,比較方便簡(jiǎn)單败玉。如果是純React Native項(xiàng)目敌土,則可以考慮手動(dòng)接入。(因?yàn)槲覝y(cè)試用的是原生集成項(xiàng)目绒怨,所以就使用了cocoaPods)
方式一:cocoaPods接入
1)修改Podfile文件:(自己注意路徑哈)
pod 'CodePush', :path => './node_modules/react-native-code-push'
2)執(zhí)行命令行更新pod:
pod install // 或者 pod install --verbose --no-repo-update
方式二:手動(dòng)接入
1)將react-native-code-push文件夾中 CodePush.xcodeproj 直接拉入項(xiàng)目中Libraries中
CodePush.xcodeproj 拉入項(xiàng)目.png
2)在Link Binary With Libraries中添加Libraries/CodePush.xcodeproj /Products中的libCodePush.a以及l(fā)ibz.tbd纯赎。
[圖片上傳中谦疾。南蹂。。(10)]Link Binary With Libraries.png
3)在Build Settings的Header Search Paths那一項(xiàng)中加入(路徑要注意)
$(SRCROOT)/../node_modules/react-native-code-push
[圖片上傳中念恍。六剥。。(11)]Header Search Paths.png
方式三:RNPM接入
好像是官方推薦使用最簡(jiǎn)單的方式峰伙,不過(guò)沒(méi)有試過(guò)哈1)安裝rnpm
$ npm -g install rnpm xcode
2)使用
$ rpm link
修改項(xiàng)目配置
1)在命令行下使用code-push deployment ls <AppName> --displayKeys 查出Staging的值疗疟,在info.plist文件中添加CodePushDeploymentKey并且把Staging的值填入。2)在Info.plist中將Bundle versions string, short的值修改為1.0.0(或者其它瞳氓,結(jié)構(gòu)一樣為x.x.x策彤,且和之后code push更新的版本要對(duì)應(yīng))
[圖片上傳中。匣摘。店诗。(12)]info.plist配置.png修改OC代碼和JS代碼
1)在加載 js bundle的類(lèi)中 修改代碼
a)首先,引入頭文件:
import "CodePush.h"
b)然后修改jsCodeLocation值:
//該文章是討論在Release下進(jìn)行相關(guān)的操作音榜,如果是debug版本加上如下代碼庞瘸,系統(tǒng)在運(yùn)行時(shí)候會(huì)自動(dòng)切換。NSURL *jsCodeLocation;#ifdef DEBUG jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil];#else jsCodeLocation = [CodePush bundleURL];#endif//如果本地js離線包不是命名main.jsbundle,需要對(duì)CodePush進(jìn)行相應(yīng)設(shè)置jsCodeLocation = [CodePush bundleURLForResource:@"index"];
2)在js文件中(該項(xiàng)目文件是index.ios.js) 修改代碼
a)引入對(duì)應(yīng)頭文件
import codePush from "react-native-code-push";
b)在componentDidMount調(diào)用sync方法赠叼,當(dāng)你的App啟動(dòng)的時(shí)候會(huì)在后臺(tái)更新
componentDidMount(){ codePush.sync(); }
- 發(fā)布更新
1)發(fā)布更新 (JavaScript-only)
當(dāng)你修改js文件的時(shí)候擦囊,并且想立刻發(fā)布。則僅僅需要以下的操作:
將你修改的js文件(當(dāng)前文件是index.ios.js)打包為二進(jìn)制文件嘴办,放入指定的地方(當(dāng)前位置為根目錄)瞬场。react-native bundle --platform ios --entry-file index.ios.js --bundle-output codepush.js --dev false
將二進(jìn)制文件push到staging 環(huán)境中code-push release [--deploymentName ] [--description ] [--mandatory]eg:code-push release NativeTest codepush.js 1.0.0
2)發(fā)布更新 (JavaScript + images)
–assets-dest 就是你放圖片的位置(當(dāng)前僅僅是做測(cè)試,實(shí)際上最好建個(gè)文件夾專(zhuān)門(mén)存入相關(guān)圖片)react-native bundle --platform ios --entry-file index.ios.js --bundle-output ./main.jsbundle --assets-dest ./<img 地址>// main.jsbundle 為自定義名字的bundle名
push bundle文件code-push <release/debug> <projectName(與注冊(cè)的app同名)><bundle文件名> <版本號(hào)>eg:code-push release NativeTest main.jsbundle 1.0.0
到這一步的時(shí)候涧郊,正常來(lái)說(shuō)贯被,該配置的都配置了,試著更新一個(gè)版本push到codepush上底燎,運(yùn)行下項(xiàng)目刃榨,就會(huì)出現(xiàn)效果。注意:如果出現(xiàn)找不到main.jsbundle的報(bào)錯(cuò)双仍,很大的原因就是沒(méi)有在本地打個(gè)離線包枢希,詳細(xì)參考這篇文章的第一部分。(曾經(jīng)因?yàn)檫@個(gè)原因朱沃,我看著報(bào)錯(cuò)發(fā)呆了好久苞轿,上網(wǎng)也找不到任何說(shuō)法??)
Q&A
CodePush更新規(guī)則[圖片上傳中茅诱。。搬卒。(13)]CodePush更新規(guī)則.png
更新后都需要重啟才能看到最新的變化 再次進(jìn)入后要等一會(huì)瑟俭。TODO:還要驗(yàn)證后確定穩(wěn)定時(shí)機(jī)。
查看歷史上傳過(guò)的版本:code-push deployment history NativeTest Staging
[圖片上傳中契邀。摆寄。。(14)]查看歷史上傳過(guò)的版本.png