react-native-code-push热更新

前期准备

官方链接

环境

本文测试都是基于以下配置进行测试

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
info
React Native Environment Info:
System:
OS: macOS 10.14.5
CPU: (4) x64 Intel(R) Core(TM) i3-8100B CPU @ 3.60GHz
Memory: 192.60 MB / 8.00 GB
Shell: 5.3 - /bin/zsh
Binaries:
Node: 12.10.0 - /usr/local/bin/node
Yarn: 1.17.3 - ~/.yarn/bin/yarn
npm: 6.11.3 - /usr/local/bin/npm
Watchman: 4.9.0 - /usr/local/bin/watchman
SDKs:
iOS SDK:
Platforms: iOS 13.2, DriverKit 19.0, macOS 10.15, tvOS 13.2, watchOS 6.1
Android SDK:
API Levels: 23, 26, 27, 28
Build Tools: 23.0.1, 26.0.1, 27.0.3, 28.0.2, 28.0.3
System Images: android-23 | Intel x86 Atom_64, android-23 | Google APIs Intel x86 Atom, android-23 | Google APIs Intel x86 Atom_64, android-26 | Google APIs Intel x86 Atom, android-27 | Intel x86 Atom_64, android-27 | Google APIs Intel x86 Atom, android-27 | Google Play Intel x86 Atom, android-28 | Google Play Intel x86 Atom
IDEs:
Android Studio: 3.5 AI-191.8026.42.35.5977832
Xcode: 11.3.1/11C505 - /usr/bin/xcodebuild
npmPackages:
react: 16.8.3 => 16.8.3
react-native: 0.59.9 => 0.59.9
npmGlobalPackages:
react-native-cli: 2.0.1
react-native-demo-for-npm: 1.0.16
react-native-update-cli: 0.1.0

过程

1. Install the App Center CLI

要管理大多数CodePush功能,需要使用App Center CLI。通过以下命令安装

1
npm install -g appcenter-cli

注意:官方提示,不要使用sudo权限来执行安装这个命令。

在成功安装App Center CLI后,执行下面的命令来配置你的App Center账户详情

1
appcenter login

账户信息:

1
Logged in as wankeenergy-gmail.com
1.1 在App Center上创建App
  • iOS
1
appcenter apps create -d PowerPlus-iOS -o iOS -p React-Native

创建成功输出类似如下

1
2
3
4
5
6
7
8
9
10
11
12
13
➜  SolarEnergy git:(dev_chenlong) ✗ appcenter apps create -d PowerPlus-iOS -o iOS -p React-Native
App Secret: 28a33816-6bc0-4b00-8947-97b28e7780e4
Description:
Display Name: PowerPlus-iOS
Name: PowerPlus-iOS
OS: iOS
Platform: React-Native
Release Type:
Owner ID: 20273273-6efd-459d-bb13-5cf102ba28d4
Owner Display Name: Energy Wanke
Owner Email: wankeenergy@gmail.com
Owner Name: wankeenergy-gmail.com
Azure Subscription ID:
  • Android
1
appcenter apps create -d PowerPlus-Android -o Android -p React-Native

我们可以把App Center上的应用程序PowerPlus-iOS设置为当前的应用程序

1
appcenter apps set-current wankeenergy-gmail.com/PowerPlus-iOS

设置测试(Staging))和 生产(Production)环境密钥,这样的话避免测试的时候应用到生产环境

1
2
appcenter codepush deployment add -a <ownerName>/<appName> Staging
appcenter codepush deployment add -a <ownerName>/<appName> Production

由于我们刚才使用appcenter apps set-current设置了PowerPlus-iOS设置为当前的应用程序, 所以直接

1
appcenter codepush deployment add Staging

输出如下

1
2
➜  SolarEnergy git:(dev_chenlong) ✗ appcenter codepush deployment add Staging
Deployment Staging has been created for wankeenergy-gmail.com/PowerPlus-iOS with key _aoveTNJlRogvD_AZL16sr1dYl-JIG-moOdTY

部署生产环境

1
2
➜  SolarEnergy git:(dev_chenlong) ✗ appcenter codepush deployment add Production
Deployment Production has been created for wankeenergy-gmail.com/PowerPlus-iOS with key ZqjsB9UA9BX5KylIOgNU4lCkSlDwCRVZudOoH

将当前应用程序设置成Android

1
appcenter apps set-current wankeenergy-gmail.com/PowerPlus-Android
1
2
3
4
5
➜  SolarEnergy git:(dev_chenlong) ✗ appcenter codepush deployment add Staging
Deployment Staging has been created for wankeenergy-gmail.com/PowerPlus-Android with key tFRH5R1fNGA_BTQ_P4ixCiR4v6TsEUL4iSMZj

➜ SolarEnergy git:(dev_chenlong) ✗ appcenter codepush deployment add Production
Deployment Production has been created for wankeenergy-gmail.com/PowerPlus-Android with key Daj3dgNAeyKYFzAqWGWfoV9PggYm8eX76vbMC

可以使用下面的命令来查看当前应用程序的部署key

1
➜  SolarEnergy git:(dev_chenlong) ✗ appcenter codepush deployment list --displayKeys

输出如下

Name Key
Staging tFRH5R1fNGA_BTQ_P4ixCiR4v6TsEUL4iSMZj
Production Daj3dgNAeyKYFzAqWGWfoV9PggYm8eX76vbMC

如果想改变已命名的应用程序名,可以使用如下命令

1
appcenter apps update -n <newName> -a <ownerName>/<appName>

要想从服务器上移除app,可以使用如下命令(要注意,如果删除,则无法再更新app

1
appcenter apps delete -a <ownerName>/<appName>

如果想要列举所有在App Center服务器上的app,可以运行如下命令

1
appcenter apps list

比如

1
2
3
➜  SolarEnergy git:(dev_chenlong) ✗ appcenter apps list
* wankeenergy-gmail.com/PowerPlus-Android (current app)
wankeenergy-gmail.com/PowerPlus-iOS

回滚版本

1
appcenter codepush rollback

2. CodePush-ify你的app

添加CodePush client SDK到你的app,通过配置,从App Center中拉取所部署的app更新, 详情可参考

2.1 开始
1
npm install --save react-native-code-push@5.7.0

AndroidiOS的配置方式有所不同,要注意的是,官方推荐为每一个平台单独创建一个CodePush应用程序。如果你想要看一下其他工程如何集成CodePush,可以看一下社区提供的一些样例app: example apps。此外,如果你想快速熟悉CodePush + React Native,可以看一下这些人制作的视频:Bilal BudhaniDeepak Sisodiya

2.2 iOS设置(这里按RN版本小于0.6来安装,因为我是0.59.9)
1
react-native link react-native-code-push

上面这个命令会提示输入一个部署key(这个key就是上面已经添加的StagingProduction),可以按回车键忽略,后面再配置也可以,可以通过以下命令来获取部署key

1
appcenter codepush deployment list -a <ownerName>/<appName> --displayKeys
2.3 到这里之后,我们运行react-native run-android可能会报错如下:
1
2
3
4
5
* What went wrong:
Execution failed for task ':app:transformDexArchiveWithDexMergerForDebug'.
> com.android.build.api.transform.TransformException: java.lang.RuntimeException: java.lang.RuntimeException: com.android.builder.dexing.DexArchiveMergerException: Error while merging dex archives:
The number of method references in a .dex file cannot exceed 64K.
Learn how to resolve this issue at https://developer.android.com/tools/building/multidex.html

解决办法,在android/app/build.gradle下添加

1
2
3
4
5
6
7
8
9
10
11
12
13
14
android {

...

defaultConfig {

...

// Enabling multidex support.
multiDexEnabled true
}

...
}
2.4 在项目根组件添加CodePush
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
import codePush from "react-native-code-push";

class MyApp extends Component {

componentDidMount() {
/*
注意:如果我们分别在Android和iOS中配置了 Staging 和 Production 密钥,那么我们这里可以
不需要deploymentKey!!!当然,要传也没有关系,传的话就是代表动态使用这个 deploymentKey,会覆
盖在工程中配置的key,看个人的选择!
*/
const deploymentKey = isAndroid ? 'tFRH5R1fNGA_BTQ_P4ixCiR4v6TsEUL4iSMZj' : '_aoveTNJlRogvD_AZL16sr1dYl-JIG-moOdTY';
codePush.sync({
updateDialog: false,
installMode: codePush.InstallMode.ON_NEXT_RESTART,
deploymentKey: deploymentKey,
}, status => {
__DEV__ && console.warn(`status: ${status}`)
}, progress => {
const {totalBytes, receivedBytes} = progress;
__DEV__ && console.warn(`totalBytes: ${totalBytes}, receivedBytes: ${receivedBytes}`);
});
}

}

MyApp = codePush(MyApp);

3. 部署测试和生产环境密钥进行多端测试

Multi-Deployment Testing

4. 发布app更新

注意:Android打包测试热更新的时候用下面这个命令

1
./gradlew assembleReleaseStaging

如果用./gradlew assembleRelease的话,默认走的是Production

如果需要直接在本地调试安装在android手机上的Staging版本,可以执行

1
react-native run-android --variant=releaseStaging

iOS打包需要在archive的时候选择Staging,否则打的也是Production

在更新代码后,使用App Center CLI发布更新到App Center,根据下面发布即可

React Native

执行App Center CLIrelease-react命令来打包代码和asset文件,然后发布到App Center server作为一个新的发布。例如

1
appcenter codepush release-react -a <ownerName>/MyApp

App Center CLI的一个重要特性就是可以使用appcenter apps set-current <ownerName>/<appName>把一个app设置为当前的app. 通过把app设置为当前app,就没有必要使用-a标志。例如,命令appcenter codepush deployment list -a <ownerName>/<appName>可以用appcenter codepush deployment list来代替。你也可以使用命令appcenter apps get-current来查看哪个app被设置成你账号的当前app

发布一个更新(加-m就是强制更新,会立即重启app),并带有日志描述

1
2
3
4
5
// 强制立即重启
appcenter codepush release-react -a <ownerName>/MyApp-iOS -m --description "Modified the header color"

// 不强制立即重启
appcenter codepush release-react -a <ownerName>/MyApp-iOS --description "Modified the header color"

发布更新到具体的版本

1
appcenter codepush release-react -a <ownerName>/MyApp-Android  --target-binary-version "1.1.0"

也可以指定范围要发布到哪些版本,参数如下

1
2
3
4
5
6
7
8
9
Range Expression	Who gets the update
1.2.3 Only devices running the specific binary version 1.2.3 of your app
* Any device configured to consume updates from your CodePush app
1.2.x Devices running major version 1, minor version 2, and any patch version of your app
1.2.3 - 1.2.7 Devices running any binary version between 1.2.3 (inclusive) and 1.2.7 (inclusive)
>=1.2.3 <1.2.7 Devices running any binary version between 1.2.3 (inclusive) and 1.2.7 (exclusive)
1.2 Equivalent to >=1.2.0 <1.3.0
~1.2.3 Equivalent to >=1.2.3 <1.3.0
^1.2.3 Equivalent to >=1.2.3 <2.0.0

要发布到生产环境还是测试环境,可以使用--deployment-name 或 -d,默认是Staging, 例如要发布到版本1.1.0的生产环境

1
appcenter codepush release-react -a <ownerName>/MyApp-Android  --target-binary-version "1.1.0" --deployment-name Production

5. 运行你的app

一旦这些步骤完成,所有运行app的用户都会收到更新。