本文由我们团队的丁武龙组内分享总结
一、相关知识
什么是code-push-server
code-push-server是基于node.js+mysql搭建自己的热更新服务器,
什么是CodePush
CodePush是微软开发的一个云服务器,通过它,开发者可以直接在用户的设备上部署手机应用更新。CodePush相当于一个中心仓库,开发者可以推送当前的更新(包括JS/HTML/CSS/IMAGE等)到CoduPush,然后应用将会查询是否有更新,由于codePush服务器在国外,国内使用的话速度并不是很快,所以就准备自建CodePush服务器
RN热更新工作原理
在自建CodePush服务器的之前,首先要了解的是RN热更新他的工作原理如下图
二、server端初始化
1.安装code-push-server
在安装code-push-server之前,先安装以下几个依赖
安装 react-native-cli react-native命令行工具,安装后可以在终端使用react-native命令
npm i -g react-native-cli
安装code-push-cli 连接微软云端,管理发布更新版本命令行工具,安装后可以在终端使用code-push命令
npm i -g code-push-cli
安装react-native-code-push 集成到react-native项目
yarn add react-native-code-push
react-native link react-native-code-push
安装code-push-server
文档提供了两种安装code-push-server的方式
-
使用npm安装
npm install code-push-server -g -
手动安装(官方推荐),因为code-push-server可能需要自己配置修改,所以建议手动安装
git clone https://github.com/lisong/code-push-server npm install
2.安装mysql并启动
直接去官网下载按照步骤一步一步安装即可
3.初始化mysql数据库
终端输入:
code-push-server-db init --dbhost localhost --dbuser root --dbpassword
初始化数据库遇到的坑
1.初始化时提示
原因:没有输入数据库密码,只需要在终端输入
code-push-server-db init --dbhost localhost --dbuser root --dbpassword ‘你的数据库密码’
2.提示数据库表已存在
解决办法:重新创建一个表,终端输入:
code-push-server-db init --dbname '表名' --dbhost localhost --dbuser root --dbpassword '密码'
出现提示更新数据库问题:
终端执行:bin/db upgrade --dbhost localhost --dbuser root --dbpassword '密码'
如果还行不通,那就只有删掉数据库重新走一遍了
三、server端修改config.js配置并启动服务
首先找到code-push-server文件夹下面的config.js文件,我的路径/usr/local/lib/node_modules/code-push-server/config/config.js,修改配置如下
db: {
username: "root",
password: "12345678",
database: "codepush",
host: "127.0.0.1",
dialect: "mysql"
},
//文件存储在本地配置 当storageType为local时需要配置
local: {
storageDir: "/Users/lizhao/Desktop/hotUpdateDemo/workspace/storage",
//文件下载地址 CodePush Server 地址 + '/download' download对应app.js里面的地址
downloadUrl: "http://localhost:3000/download"
},
jwt: {
// 登录jwt签名密钥,必须更改,否则有安全隐患,可以使用随机生成的字符串
// Recommended: 63 random alpha-numeric characters
// Generate using: https://www.grc.com/passwords.htm
tokenSecret: 'INSERT_RANDOM_TOKEN_KEY'
},
common: {
dataDir: "/Users/lizhao/Desktop/hotUpdateDemo/workspace/storage",
//选择存储类型,目前支持local和qiniu配置
storageType: "local"
},
配置好了之后,就开始启动服务器吧,在终端输入
./bin/www
如果没有报错的话,那就说明启动成功
到了这里,code-push-server服务端已经配置好了
三、客户端集成
1.创建服务端应用
基于code-push-server服务
终端输入
code-push login http://127.0.0.1:3000 #浏览器中登录获取token复制到终端 账号admin 密码123456
code-push app add AppDemo ios react-native #创建ios版本App,获取Production DeploymentKey并 记录下来
登录可能出现的问题
- 在终端输入code-push login的时候,如果出现
[Error] You are already logged in from this machine.的时候,在终端试着输入命令:code push logout,如果出现[Error] connect ECONNREFUSED 127.0.0.1:3000错误,可以直接删除 ~/.code-push.config文件
2.配置iOS工程
1.打开info.plist , 添加CodePushDeploymentKey 和CodePushServerURL
1.CodePushDeploymentKey值为AppDemo的DeploymentKey
2.CodePushServerURL 值设置为code-push-server服务器地址,模拟器调试时候设置为 http://127.0.0.1:3000/ 真机模式下,请设置为外网ip或者域名地址
修改AppDelegate.m
因为前面已经link过了react-native-code-push,所以不需要手动链接,在Appdelegate.m文件里,修改以下代码
#import "AppDelegate.h"
#import <CodePush/CodePush.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
...
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSURL *jsCodeLocation;
#ifdef DEBUG
jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
#else
jsCodeLocation = [CodePush bundleURL];
#endif
NSLog(@"jsCodeLocation == %@",jsCodeLocation);
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
moduleName:@"hotUpdateDemo"
initialProperties:nil
launchOptions:launchOptions];
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;
}
...
3.添加更新检查
1.引入react-native-code-push
import CodePush from "react-native-code-push"
在App.js入口componentDidMount方法添加
componentDidMount() {
CodePush.sync({
//在更新配置中通过指定installMode来决定安装完成的重启时机 总共有三种,分别是 ON_NEXT_RESUME(装完成后会在应用进入后台后重启更新)、ON_NEXT_RESTART(安装完成后会在下次重启后进行更新)、IMMEDIATE(表示安装完成立即重启更新)
installMode: CodePush.InstallMode.IMMEDIATE,
updateDialog: true //是否显示更新弹窗
});
}
2.发布更新
发布更新之前,需要先将js包打包成bundle,终端输入
react-native bundle --platform ios --dev false --entry-file index.js --bundle-output
ios/main.jsbundle #运行该命令打包bundle文件
打包bundle完成之后,就可以通过codePush发布更新了,在终端输入
code-push release-react HotApp ios -d Staging #默认是打包Staging环境的,正式环境打包方式如下
code-push release-react HotApp ios -d Production #打包正式环境
------mandatory #表示是否强制更新
------description #应用更新描述