發布更新
需在項目主目錄下執行以下命令
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(); } }; }