发布更新
需在项目主目录下执行以下命令
CodePush支持两种发布更新的方式,一种是通过code-push release-react
简化方式,另外一种是通过code-push release
的复杂方式。
这里重点介绍第一种方式
第一种方式:通过
code-push release-react
发布更新
这种方式将打包与发布两个命令合二为一,可以说大大简化了我们的操作流程,建议大家多使用这种方式来发布更新。
命令格式:
code-push release-react <appName> <platform>
eg:
-
code-push release-react MyApp-iOS ios
-
code-push release-react MyApp-Android android
来个更详细的:
code-push release-react MyApp-iOS ios --t 1.0.0 --dev false --d Production --des "1.优化操作流程" --m true code-push release-react RNApp android --t 2.0.5 --dev false -d Staging --des "1.test" --m true
其中参数--t为二进制(.ipa与apk)安装包的的版本;--dev为是否启用开发者模式(默认为false);--d是要发布更新的环境分Production与Staging(默认为Staging);--des为更新说明;--m 是强制更新。
关于code-push release-react
更多可选的参数,可以在终端输入code-push release-react
进行查看。
release-react
常用命令
# Release a mandatory update with a changelog 强制更新包 code-push release-react MyApp-iOS ios -m --description "Modified the header color" # Release an update for an app that uses a non-standard entry file name, and also capture # the sourcemap file generated by react-native bundle code-push release-react MyApp-iOS ios --entryFile MyApp.js --sourcemapOutput ../maps/MyApp.map # Release a dev Android build to just 1/4 of your end users 灰度测试覆盖25%的用户 code-push release-react MyApp-Android android --rollout 25% --dev true # Release an update that targets users running any 1.1.* binary Android版本在1.1.*的用户会得到更新,其他的版本不会更新 code-push release-react MyApp-Android android --targetBinaryVersion "~1.1.0"
参数说明:
--entry-file 指定入口文件 因为要打包ios平台,所以指定为rn项目的index.ios.js作为入口
--bundle-output 指定输出的jsbundle文件路径和文件名 指定到rn项目的ios工程文件夹下,记得一定要先创建bundle文件夹,不然终端会报文件夹找不到的错误
--platform 指定平台类型
--assets-dest 指定资源文件夹路径 assets文件夹的路径,包含图片、node模块等资源
--dev 是否为开发模式 如果设置为false,不会产生警告,并且bundle会被压缩
CodePush客户端支持差异更新,因此即使您在每次更新时发布JS包和资源,您的最终用户也只会实际下载所需的文件。
有关release-react
命令如何工作的更多详细信息,以及它公开的各种参数,请参阅CLI文档。此外,如果您希望自己处理react-native bundle
命令,因此需要更灵活的解决方案release-react
,请参阅release
命令以获取更多详细信息
注意:
- CodePush默认是更新 staging 环境的,如果是staging,则不需要填写 deploymentName。
- 如果有 mandatory 则Code Push会根据mandatory 是true或false来控制应用是否强制更新。默认情况下mandatory为false即不强制更新。
- 对应的应用版本(targetBinaryVersion)是指当前app的版本(对应build.gradle中设置的versionName "2.0.5"),也就是说此次更新的js/images对应的是app的那个版本。不要将其理解为这次js更新的版本。
如客户端版本是 2.0.5,那么我们对2.0.5的客户端更新js/images,targetBinaryVersion填的就是2.0.5。 - 对于对某个应用版本进行多次更新的情况,CodePush会检查每次上传的 bundle,如果在该版本下如2.0.5已经存在与这次上传完全一样的bundle(对应一个版本有两个bundle的md5完全一样),那么CodePush会拒绝此次更新。
如图:
对应一个版本有两个bundle的md5完全一样
所以如果我们要对某一个应用版本进行多次更新,只需要上传与上次不同的bundle/images即可。如:
eg:
对2.0.5的版本进行第一次更新:
code-push release-react RNApp android --t 2.0.5 --dev false -d Staging --des "1.test" --m true
对2.0.5的版本进行第二次更新(Js或image修改再次发布):
code-push release-react RNApp android --t 2.0.5 --dev false -d Staging --des "2.testAgain" --m true
- 在终端输入
code-push deployment history <appName> Staging
可以看到Staging版本更新的时间、描述等等属性。
实际发布更新时常用操作步骤
-
-
登录:
code-push login
-
列出账号下的所有项目:
code-push app list
-
列出应用的部署:
code-push deployment ls MyApp
-
查看部署的历史版本信息:
code-push deployment history MyApp Staging
-
发布版本更新:
code-push release-react MyApp ios -d Staging --des 'UI调整' --t '1.0.0'
-
把更新推到另一个环境:
code-push promote MyApp Staging Production
-
Debugging / Troubleshooting
如果使用真机,必须先把手机跟电脑连接
执行code-push debug android, 就可以看到debug信息
官网提供的一些问题和解决方法
Issue / Symptom | Possible Solution |
---|---|
Compilation Error | Double-check that your version of React Native is compatible with the CodePush version you are using. |
Network timeout / hang when calling sync or checkForUpdate in the iOS Simulator |
Try resetting the simulator by selecting the Simulator -> Reset Content and Settings.. menu item, and then re-running your app. |
Server responds with a 404 when calling sync or checkForUpdate |
Double-check that the deployment key you added to your Info.plist (iOS), build.gradle (Android) or that you're passing to sync /checkForUpdate , is in fact correct. You can run appcenter codepush deployment list <ownerName>/<appName> --displayKeys to view the correct keys for your app deployments. |
Update not being discovered | Double-check that the version of your running app (like 1.0.0 ) matches the version you specified when releasing the update to CodePush. Additionally, make sure that you are releasing to the same deployment that your app is configured to sync with. |
Update not being displayed after restart | If you're not calling sync on app start (like within componentDidMount of your root component), then you need to explicitly call notifyApplicationReady on app start, otherwise, the plugin will think your update failed and roll it back. |
I've released an update for iOS but my Android app also shows an update and it breaks it | Be sure you have different deployment keys for each platform in order to receive updates correctly |
I've released new update but changes are not reflected | Be sure that you are running app in modes other than Debug. In Debug mode, React Native app always downloads JS bundle generated by packager, so JS bundle downloaded by CodePush does not apply. |
No JS bundle is being found when running your app against the iOS simulator | By default, React Native doesn't generate your JS bundle when running against the simulator. Therefore, if you're using [CodePush bundleURL] , and targetting the iOS simulator, you may be getting a nil result. This issue will be fixed in RN 0.22.0, but only for release builds. You can unblock this scenario right now by making this change locally. |
若提示“Update is invalid - A JS bundle file named "null" could not be found within the downloaded contents. Please check that you are releasing your CodePush updates using the exact same JS bundle file name that was shipped with your app's binary”
检车 MainApplication.java
中protected String getJSBundleFile()这个方法有没有写对
// 1. Import the plugin class. import com.microsoft.codepush.react.CodePush; public class MainApplication extends Application implements ReactApplication { private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) { ... // 2. Override the getJSBundleFile method in order to let // the CodePush runtime determine where to get the JS // bundle location from on each app start @Override protected String getJSBundleFile() { return CodePush.getJSBundleFile(); } }; }