
本文介紹搭建熱更服務(wù)器并在手機(jī)上測試react native熱更的全過程。
>>>我的博客<<<
安裝MySQL
安裝完成后,會彈出初始密碼,粗細(xì)的我,隨手點(diǎn)了OK,此處挖坑半天。

code-push熱更服務(wù)器搭建:
安裝code-push-server
- npm安裝
# 安裝code-push-server
npm install code-push-server -g
- 源碼安裝(推薦)
# 從git庫下載最新代碼
git clone https://github.com/lisong/code-push-server.git
# 進(jìn)入到code-push-server目錄
cd code-push-server
# 安裝
npm install
Code-Push-Server配置
修改config/config.js文件,指定數(shù)據(jù)庫,數(shù)據(jù)存放位置
- 配置數(shù)據(jù)庫
db: {
username: "root",
password: "Your PWD",
database: "codepush",
host: "127.0.0.1",
port: 3306,
dialect: "mysql"
}
- 配置存儲(默認(rèn)為local,本次也采用local)
common: {
// dataDir用于進(jìn)行存放比對文件
dataDir: "/Users/tablee/workspaces/data",
// 存儲類型,可選值有l(wèi)ocal,oss,qiniu,s3
storageType: "local"
},
// 文件存儲在本地 當(dāng)storageType為local時(shí)需要配置
local: {
// 二進(jìn)制文件存放目錄,文件下載目錄,不要使用臨時(shí)目錄
storageDir: "/Users/tablee/workspaces/storage",
// 文件下載地址 CodePushServer地址 + ’/download‘,download對應(yīng)app.js里面的地址
//默認(rèn)此處的下載地址是127.0.0.1:3000這個自然是錯誤的,要外網(wǎng)ip地址
downloadUrl: "https://tech.haier.net:7788/download",
// public static download spacename
public: '/download'
},
//七牛云存儲配置 當(dāng)storageType為qiniu時(shí)需要配置
qiniu: {
accessKey: "",
secretKey: "",
bucketName: "",
//文件下載域名地址
downloadUrl: ""
},
//阿里云存儲配置 當(dāng)storageType為oss時(shí)需要配置
oss: {
accessKeyId: "",
secretAccessKey: "",
endpoint: "",
bucketName: "",
// 對象Key的前綴,允許放到子文件夾里面
prefix: "",
// 文件下載域名地址,需要包含前綴
downloadUrl: "",
}
- 配置簽名,可以不修改,但是推薦更改
jwt: {
// 登錄jwt簽名密鑰,必須更改,否則有安全隱患,可以使用隨機(jī)生成的字符串
// Recommended: 63 random alpha-numeric characters
// Generate using: https://www.grc.com/passwords.htm
tokenSecret: 'https://www.grc.com/passwords.htm'
}
初始化數(shù)據(jù)庫
配置完成后,進(jìn)行數(shù)據(jù)初始化工作
- npm安裝
# 初始化數(shù)據(jù)庫,**替換為數(shù)據(jù)庫密碼**(參考后面配置說明)
code-push-server-db init --dbhost localhost --dbuser root --dbpassword **Your PWD** --dbport 3306
- 源碼安裝
# 初始化數(shù)據(jù)庫
./bin/db init --dbhost localhost --dbuser root --dbpassword **Your PWD** --dbport 3306
注意事項(xiàng):
- 不論采取哪種安裝方式,初始化數(shù)據(jù)庫時(shí)要保證數(shù)據(jù)庫用戶名密碼正確;數(shù)據(jù)庫中不能存在codepush數(shù)據(jù)庫(默認(rèn)數(shù)據(jù)庫為codepush)
- 采用源碼安裝,執(zhí)行bin目錄下的db命令時(shí),要保證此文件具有可執(zhí)行權(quán)限,如果沒有,需要添加權(quán)限
# 添加db文件的可執(zhí)行權(quán)限
chmod +x bin/db
- 如果數(shù)據(jù)庫密碼復(fù)雜,帶有特殊符號,初始化語句將執(zhí)行失敗。此時(shí)因?yàn)槭堑谝淮伟惭b,可以在數(shù)據(jù)庫服務(wù)器手動創(chuàng)建名為
codepush(必須是這個名字)的數(shù)據(jù)庫,然后執(zhí)行/opt/chuangke/code-push-server/sql/目錄下的codepush-all.sql腳本來初始化數(shù)據(jù)庫。
初始化成功后數(shù)據(jù)庫中的表如下:
codepush database
- 如果數(shù)據(jù)庫密碼復(fù)雜,帶有特殊符號,初始化語句將執(zhí)行失敗。此時(shí)因?yàn)槭堑谝淮伟惭b,可以在數(shù)據(jù)庫服務(wù)器手動創(chuàng)建名為
服務(wù)啟動
安裝配置文件中的目錄結(jié)構(gòu),到/Users目錄中建立如下文件夾 /Users/tablee/workspaces/storage
- npm啟動
# 啟動服務(wù),默認(rèn)使用3000端口,可以在瀏覽器中打開 http://127.0.0.1:3000
code-push-server
# 指定端口號運(yùn)行
PORT=3000 HOST=127.0.0.1 NODE_ENV=production code-push-server
- 源碼啟動
# 啟動服務(wù)(保證www具有可執(zhí)行權(quán)限),在瀏覽器中打開 http://127.0.0.1:3000
./bin/www
# 以守護(hù)進(jìn)程的方式運(yùn)行
nohup ./bin/www &
# 指定端口號運(yùn)行
PORT=3000 HOST=127.0.0.1 NODE_ENV=production node ./bin/www
- forever 后臺啟動(推薦)
先安裝forever
當(dāng)然,有人說forever已經(jīng)過時(shí)了,推薦使用pm2代替forever,請參考linux npm start 保持后臺運(yùn)行
# 全局安裝
$ npm install forever -g
# 查看是否安裝成功
$ forever list
info: No forever processes running
很抱歉,如果不順利的話,會有這么個情況
[root@izm5e3m6sxwr4dw9w7r6h4z lib]# npm install forever -g
/opt/software/node-v10.0.0-linux-x64/bin/forever -> /opt/software/node-v10.0.0-linux-x64/lib/node_modules/forever/bin/forever
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.7 (node_modules/forever/node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.7: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})
+ forever@0.15.3
updated 1 package in 2.109s
[root@izm5e3m6sxwr4dw9w7r6h4z lib]# forever list
-bash: forever: 未找到命令
[root@izm5e3m6sxwr4dw9w7r6h4z lib]#
不美麗了,命名安裝成功了,但是還是提示找不到命令,怎么辦呢?我來教你,這個是因?yàn)檫@個-g是吧命令安裝到了node所在目錄,可以看看具體在哪
[root@izm5e3m6sxwr4dw9w7r6h4z ~]# npm list -g --depth 0
/opt/software/node-v10.0.0-linux-x64/lib
├── forever@0.15.3
└── npm@5.6.0
[root@izm5e3m6sxwr4dw9w7r6h4z ~]# cd /opt/software/node-v10.0.0-linux-x64/lib
[root@izm5e3m6sxwr4dw9w7r6h4z lib]# ls
node_modules
[root@izm5e3m6sxwr4dw9w7r6h4z lib]# cd node_modules/forever/bin/
[root@izm5e3m6sxwr4dw9w7r6h4z bin]# ls
forever monitor
[root@izm5e3m6sxwr4dw9w7r6h4z bin]#
這次是真的看見forever被安裝到哪里,接下來就來個軟鏈到/usr/bin下就可以了
[root@izm5e3m6sxwr4dw9w7r6h4z bin]# ln -s /opt/software/node-v10.0.0-linux-x64/lib/node_modules/forever/bin/forever /usr/bin/forever
[root@izm5e3m6sxwr4dw9w7r6h4z bin]# forever list
info: No forever processes running
[root@izm5e3m6sxwr4dw9w7r6h4z bin]#
完美,接著使用forever啟動應(yīng)用啦。
比如我的server源碼的位置在/opt/chuangke/code-push-server/,在當(dāng)前目錄下執(zhí)行如下命令啟動
NODE_ENV=production forever start -l log/forever.log -o log/info.log -e log/err.log bin/www
可以用如下絕對路徑命令啟動:
NODE_ENV=production forever start -l /opt/chuangke/code-push-server/log/forever.log -o /home/haieradmin/codepush/code-push-server/log/info.log -e /home/haieradmin/codepush/code-push-server/log/err.log /home/haieradmin/codepush/code-push-server/bin/www
- 服務(wù)啟動驗(yàn)證
命令行驗(yàn)證
$ forever list
info: Forever processes running
data: uid command script forever pid id logfile uptime
data: [0] 8Or8 /usr/local/node8/bin/node /opt/chuangke/code-push-server/bin/www 60199 60209 /opt/chuangke/code-push-server/log/forever.log 0:15:2:21.503
如果服務(wù)器啟動成功,則用瀏覽器訪問默認(rèn)的3000端口,可以看到如下效果

到此服務(wù)器端到配置就完成了。
客戶端熱更驗(yàn)證
客戶端測試代碼以 https://github.com/lisong/code-push-demo-app 為例
客戶端安裝code-push-cli
# 全局安裝
$ npm install -g code-push-cli
# 查看版本
$ code-push -v
2.1.8
下載客戶端驗(yàn)證程序,并安裝第一版
- clone程序并install
$ git clone git@github.com:lisong/code-push-demo-app.git
# cd 到demo路徑,執(zhí)行npm install 安裝node依賴包
$ cd code-push-demo-app
$ npm install
打開命令終端,登錄code-push-server服務(wù)器,這里配置為local,所以登錄地址為http://127.0.0.1:3000
$ code-push login http://127.0.0.1:3000 //賬號密碼為博主提供 account: admin password: 123456
登錄成功之后獲取token
將文本框中的key復(fù)制粘貼到登錄終端,點(diǎn)擊回車登錄成功

輸入賬號密碼,點(diǎn)擊登錄。獲取token:

$ code-push login http://127.0.0.1:3000
Please login to Mobile Center in the browser window we've just opened.
Enter your token from the browser: HugyOJpzvzhEhB05galUftoL4zrz4ksvOXqog
Successfully logged-in. Your session file was written to C:\Users\marvin\AppData\Local\.code-push.config. You can run the code-push logout command at any time to delete this file and terminate your session.
在命令行查看當(dāng)前熱更服務(wù)器的部署信息,
$ code-push app list
┌──────┬─────────────┐
│ Name │ Deployments │
└──────┴─────────────┘
- 添加新的APP(以安卓為例)
# 安卓版
$ code-push app add CodePushReactNativeDemo-android react-native
Successfully added the "CodePushReactNativeDemo-android" app, along with the following default deployments:
┌────────────┬───────────────────────────────────────┐
│ Name │ Deployment Key │
├────────────┼───────────────────────────────────────┤
│ Production │ VKNbn9Oe5Wj9bPoGkYCUVuzRuqHV4ksvOXqog │
├────────────┼───────────────────────────────────────┤
│ Staging │ 6KfLoVvhgdsnFzFCIohRb2t5grmD4ksvOXqog │
└────────────┴───────────────────────────────────────┘
# 再運(yùn)行命令查看
$ code-push app list
┌─────────────────────────────────┬─────────────────────┐
│ Name │ Deployments │
├─────────────────────────────────┼─────────────────────┤
│ CodePushReactNativeDemo-android │ Production, Staging │
└─────────────────────────────────┴─────────────────────┘
- 修改配置
添加完成之后可以用code-push app list命令查看創(chuàng)建好的app,并將測試的Staging key拷貝到MainApplication.java中的 “Your Key“ 的位置,推送的時(shí)候通過key將app和服務(wù)器端關(guān)聯(lián)。
- 修改配置
用Android Studio打開code-push-demo-app/android目錄到MainApplication.java里面修改以下代碼:
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new CodePush(
"YourKey", // code-push app add項(xiàng)目后生成的app 推送key
MainApplication.this,
BuildConfig.DEBUG,
"YourCodePushServerUrl" // config.js中配置的downloadUrl 地址 不需要/download后綴
)
);
}
我的配置是:
修改MainApplication.java的代碼如下:
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new CodePushBuilder(getResources().getString(R.string.reactNativeCodePush_androidDeploymentKey),getApplicationContext())
.setIsDebugMode(BuildConfig.DEBUG)
.setServerUrl(getResources().getString(R.string.reactNativeCodePush_androidServerURL))
.build()
);
}
修改android/app/src/main/res/values/strings.xml文件,指定reactNativeCodePush_androidDeploymentKey和reactNativeCodePush_androidServerURL。
<resources>
<string moduleConfig="true" name="reactNativeCodePush_androidDeploymentKey">6KfLoVvhgdsnFzFCIohRb2t5grmD4ksvOXqog</string>
<string moduleConfig="true" name="reactNativeCodePush_androidServerURL">http://xxx.xxx:3000/</string>
<string name="app_name">CodePushDemoApp</string>
</resources>
- cd 到code-push-demo-app目錄,允許react-native start 啟動react-native 服務(wù)??梢赃x擇用數(shù)據(jù)線連接手機(jī),手機(jī)開啟開發(fā)者模式。也可以直接將
code-push-demo-app\android\app\build\outputs\apk\debug以后的apk包發(fā)送到手機(jī)上,直接打開安裝。
- cd 到code-push-demo-app目錄,允許react-native start 啟動react-native 服務(wù)??梢赃x擇用數(shù)據(jù)線連接手機(jī),手機(jī)開啟開發(fā)者模式。也可以直接將
$ react-native run-android
在手機(jī)上運(yùn)行app的截圖如下:

-
Android Studio編譯并將項(xiàng)目運(yùn)行到手機(jī)上,reload更新到最新js包在code-push-demo-app中首頁隨意做一些修改,這里是將CodePushDemoApp/App.js文件做了如下修改。
一些修改
執(zhí)行推送命令
-
# 測試環(huán)境執(zhí)行:
$ code-push release-react CodePushReactNativeDemo-android android --t 2.1.0 --d Staging --des "熱更測試" -m false
Detecting android app version:
Using the target binary version value "2.1.0" from "android\app\build.gradle".
Running "react-native bundle" command:
node node_modules\react-native\local-cli\cli.js bundle --assets-dest C:\Users\marvin\AppData\Local\Temp\CodePush\CodePush --bundle-output C:\Users\marvin\AppData\Local\Temp\CodePush\CodePush\index.android.bundle --dev false --entry-file index.js --platform android
Scanning folders for symlinks in D:\Git\oschina\react\code-push-demo-app\node_modules (101ms)
Scanning folders for symlinks in D:\Git\oschina\react\code-push-demo-app\node_modules (48ms)
Loading dependency graph, done.
bundle: Writing bundle output to: C:\Users\marvin\AppData\Local\Temp\CodePush\CodePush\index.android.bundle
bundle: Done writing bundle output
bundle: Copying 1 asset files
bundle: Done copying assets
Releasing update contents to CodePush:
Successfully released an update containing the "C:\Users\marvin\AppData\Local\Temp\CodePush\CodePush" directory to the "Staging" deployment of the "CodePushReactNativeDemo-android" app.
# 生產(chǎn)環(huán)境執(zhí)行:
$ code-push release-react CodePushReactNativeDemo-android android -d Production
#指定版本,添加注釋
$ code-push release-react CodePushReactNativeDemo-android android -d Production --des "marvin code push testing" -t "1.0.0"
Successfully 表示熱更包推送成功,然后在手機(jī)上點(diǎn)擊Press for dialog-driven sync鏈接。
彈出下載確認(rèn)

點(diǎn)擊【install】

至此,熱更服務(wù)器搭建,及android版app體驗(yàn)完畢。
擴(kuò)展
1、產(chǎn)看更新包安裝情況
# code-push deployment history appName deploymentName
code-push deployment history CodePushReactNativeDemo-android Staging
Staging 或者 Production

2、列表部署名稱
code-push deployment ls CodePushReactNativeDemo-android

3、常見錯誤
3.1、 download地址寫錯,默認(rèn)是http://127.0.0.1:3000 如果不改成外網(wǎng)域名和端口,下載將失敗。
app啟動抓包查看的結(jié)果就是,返回的下載地址無法下載到資源。

3.2、nginx限制資源大小
需要修改配置,我們的一個app打包后約70M,上傳時(shí)就報(bào)錯了,后來才知道是nginx指定的上傳大小是50M,所以要修改nginx配置文件,加上client_max_body_size 100M;這個樣配置。
3.3、數(shù)據(jù)庫配置錯誤
將數(shù)據(jù)庫的端口,或者用戶名密碼寫錯也很常見
3.4、目錄權(quán)限問題
配置文件里默認(rèn)的dataDir和storeage目錄必須有code-push運(yùn)行用戶的操作權(quán)限,否則會有以下錯誤。

常用命令
// 賬戶相關(guān)
code-push login 登陸
code-push loout 注銷
code-push access-key ls 列出登陸的token
code-push access-key rm <accessKye> 刪除某個 access-key
// app操作相關(guān)
code-push app add <appName> <platform> react-native 在賬號里面添加一個新的app
code-push app remove 或者 rm 在賬號里移除一個 app
code-push app rename 重命名一個存在 app
code-push app list 或則 ls 列出賬號下面的所有 app
code-push app transfer 把a(bǔ)pp的所有權(quán)轉(zhuǎn)移到另外一個賬號
// 應(yīng)用信息相關(guān)
code-push deployment add <appName> 部署
code-push deployment rm <appName> 刪除部署
code-push deployment rename <appName> 重命名
code-push deployment ls <appName> 列出應(yīng)用的部署情況
code-push deployment ls <appName> -k 查看部署的key
code-push deployment history <appName> <deploymentName> 查看歷史版本
// 發(fā)布
code-push release-react <appName> <platform> -t 版本 -d 環(huán)境 --des 描述 -m true (強(qiáng)制更新)
// 清除歷史部署記錄
code-push deployment clear <appName> Production or Staging
// 回滾
code-push rollback <appName> Production --targetRelease v4(codepush服務(wù)部署的版本號)
- 注意事項(xiàng):
更新規(guī)則
1> CodePush部署版本 > App版本
更新可用,但當(dāng)前版本比運(yùn)行版本高。不作更新
2> CodePush部署版本 < App版本
不執(zhí)行更新處理
3> CodePush部署版本 == App版本
自動下載更新,并根據(jù)加載策略加載最新bundle回滾
當(dāng)部署的版本不同時(shí),不能跨版本回滾。
例如:CodePush歷史版本中為2.10.1,此時(shí)發(fā)布2.10.2版本。當(dāng)從2.10.2發(fā)起回滾操作回到2.10.1時(shí),是不可行的。
- 部署信息參數(shù)
在部署了版本之后,執(zhí)行 【code-push deployment ls uniApp-Android】可以查看當(dāng)前版本、當(dāng)前部署環(huán)境下的部署信息:
- Update Metadata(更新信息)
Label:標(biāo)識當(dāng)前部署版本,每部署新版本,版本號增加1
App Version:當(dāng)前部署的App版本號
Mandatory:是否強(qiáng)制更新
Release Time:部署時(shí)間
Released By:部署用戶
Description:部署 描述信息
從上面內(nèi)容不難發(fā)現(xiàn),這些信息基本都會在我們執(zhí)行 code-push release 時(shí)配置
- Install Metrics(安裝指標(biāo))
Active:成功安裝并運(yùn)行當(dāng)前release的用戶的數(shù)量,即表示當(dāng)前下載更新部署的活躍用戶數(shù)量,of 左邊數(shù)會隨著用戶安裝、卸載而 增加、減少。of右邊數(shù)代表當(dāng)前安裝或收 到部署版本的用戶數(shù),當(dāng)有用戶卸載App,該數(shù)值會降低。
因此它很好的解釋了當(dāng)前更新包有多少活躍用戶,多少用戶接收過這個安裝包
Total:成功安裝部署當(dāng)前release的用戶量,只增不減
Pending:當(dāng)前release版本被下載的數(shù)量,但是還沒有被安裝,該值會隨著用戶下載安裝后增加, 在卸載時(shí)降低。
參考資料
code-push-server 搭建自己的推送服務(wù)器流程
熱更新(android)windows系統(tǒng)code-push-server 的使用
ReactNative集成CodePush教程 集成Code Push的案例說明
react-native熱更新全方位講解

