動態

詳情 返回 返回

CodePush停服後,如何用騰訊Shiply快速實現ReactNative熱更新? - 動態 詳情

1.  背景

CodePush是微軟VisualStudioAppCenter服務的一個子功能,支持動態下發RN熱更新產物。但是VisualStudioAppCenter 2025/3/31 已經停止服務,如果想繼續使用CodePush需要自己獨立部署。

專門獨立部署一套後台服務,對於個人開發者尤其是客户端開發來説時間成本較高,後期維護也需要投入不少精力,最好還是使用已有的下發平台。

調研了一下發現目前Pushy和Shiply平台都支持RN熱更新。

Pushy 是ReactNative中文網推出的RN下發平台,支持差量更新,CLI和網頁雙端管理。

Shiply 是騰訊端服務團隊推出的面向客户端的全場景發佈平台,支持動態下發配置、資源、軟件包(App)、Android熱更新、flutter熱更新,最近剛上線了RN熱更新功能。
 
體驗下來感覺Shiply的前端交互更友好,有完整的審批發布流程,支持多維度的下發規則,能看到客户端下發加載數據,下面詳細介紹下Shiply RN熱更新的接入和使用過程。
 

2.  Shiply RN熱更新接入實戰

2.1.  創建Shiply項目及產品

參考第三點中的發佈平台使用指引,創建一個測試項目,並創建Android和iOS產品。

2.2.  創建RN模塊

參考第三點中的發佈平台使用指引,創建一個名叫「testRN」的模塊,綁定2.1中創建的兩個產品。

2.3.  接入Shiply RN動態化SDK

2.3.1.  創建RN demo

先創建一個RN demo工程:

npx @react-native-community/cli init TestShiplyRN --version 0.78

 

2.3.2.  添加RN層依賴

在demo項目根目錄執行

npm install rn-shiply-upgrade

 

2.3.3.  添加Android層依賴

在項目Android目錄下的build.gradle文件中添加maven地址

allprojects {
  repositories {
    maven { url "https://tencent-tds-maven.pkg.coding.net/repository/shiply/repo" }
  }
}

 

2.3.4.  添加熱更新檢查與加載代碼

2.3.4.1.  修改RN層代碼

import React from 'react';
import {Platform, Text, View} from 'react-native';
 
import { HotUpdateHelper, HotUpdateButton } from 'rn-shiply-upgrade'; // 新增導入輔助類
 
const App = () => {
    // 初始化熱更新配置(只需一次)
    HotUpdateHelper.getInstance({
        // 需要修改為業務方自己的android/ios appId和appKey
        appId: Platform.OS === 'ios' ? 'iOSAppId' : 'androidAppId',
        appKey: Platform.OS === 'ios'
            ? 'iOSAppKey'
            : 'androidAppKey',
        deviceId: '33333', // 需要修改為實際的設備id
        appVersion: "1.0.0", // 應用版本號
        shiplyResName: 'testRN', // 資源key名稱,對應shiply平台上中創建的RN模塊名字
    });
 
    return (
        <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
            <Text> 熱更新測試: 當前是本地內容</Text>
            <View style={{ height: 10 }} />
            {/* 默認樣式按鈕 */}
            <HotUpdateButton />
        </View>
            );
};
 
export default App;

 

androidAppId/androidAppKey/iOSAppId/iOSAppKey要改成2.1中創建的Android/iOS產品的真實appId/appKey。
 
 
2.3.4.2.  修改Android層代碼

class MainApplication : Application(), ReactApplication {
 
  override val reactNativeHost: ReactNativeHost =
      object : DefaultReactNativeHost(this) {
        override fun getPackages(): List<ReactPackage> =
            PackageList(this).packages.apply {
              // Packages that cannot be autolinked yet can be added manually here, for example:
              // add(MyReactNativePackage())
            }
 
        override fun getJSMainModuleName(): String = "index"
 
        override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG
 
        override fun getJSBundleFile(): String? {
              var result: String? = null
              // 從shiply獲取RN bundle路徑,業務方需要將資源key修改為shiply平台中創建的資源key名稱
              result = ShiplyReactNativeUpgradeModule.getJSBundleFilePath(applicationContext as Application, "testRN")
              Log.d("MainApplication", "getJSBundleFile: $result")
              return result
        }
 
        override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
        override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED
      }
 
  override val reactHost: ReactHost
    get() = getDefaultReactHost(applicationContext, reactNativeHost)
 
  override fun onCreate() {
    super.onCreate()
    SoLoader.init(this, OpenSourceMergedSoMapping)
    if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
      // If you opted-in for the New Architecture, we load the native entry point for this app.
      load()
    }
  }
}

複寫getJSBundleFile方法,從shiply獲取bundle路徑。

2.3.4.3.  修改iOS層代碼

class AppDelegate: RCTAppDelegate {
  override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
    self.moduleName = "TestShiplyRN"
    self.dependencyProvider = RCTAppDependencyProvider()
 
    // You can add your custom initial props in the dictionary below.
    // They will be passed down to the ViewController used by React Native.
    self.initialProps = [:]
 
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
 
  override func sourceURL(for bridge: RCTBridge) -> URL? {
    self.bundleURL()
  }
 
  override func bundleURL() -> URL? {
 
    // 業務方需要將資源key修改為shiply平台中創建的資源key名稱
    ShiplyReactNativeUpgradeUtil.getJSBundleFilePath("testRN");
    if let path = ShiplyReactNativeUpgradeUtil.getJSBundleFilePath("testRN") {
        NSLog("bundleURL called,path = %@ ", path);
        return URL(fileURLWithPath: path)
    }
    return Bundle.main.url(forResource: "main", withExtension: "jsbundle")
  }
}

複寫bundleURL方法,從shiply獲取bundle路徑。
 
做完以上步驟後就完成了接入。
 
這時點擊檢查更新沒有什麼效果,因為還沒有在shiply配置新版本RN熱更新產物。

2.4.  打包RN動態化產物

 

2.4.1.  修改Demo測試代碼

import React from 'react';
import {Platform, Text, View} from 'react-native';
 
import { HotUpdateHelper, HotUpdateButton } from 'rn-shiply-upgrade'; // 新增導入輔助類
 
const App = () => {
    // 初始化熱更新配置(只需一次)
    HotUpdateHelper.getInstance({
        // 需要修改為業務方自己的android/ios appId和appKey
        appId: Platform.OS === 'ios' ? 'iOSAppId' : 'androidAppId',
        appKey: Platform.OS === 'ios'
            ? 'iOSAppKey'
            : 'androidAppKey',
        deviceId: '33333', // 需要修改為實際的設備id
        appVersion: "1.0.0", // 應用版本號
        shiplyResName: 'testRN', // 資源key名稱,對應shiply平台上中創建的RN模塊名字
    });
 
    return (
        <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
            {/*<Text> 熱更新測試: 當前是本地內容</Text>*/}
            <Text> 熱更新測試: 當前是熱更新內容</Text>
            <View style={{ height: 10 }} />
            {/* 默認樣式按鈕 */}
            <HotUpdateButton />
        </View>
            );
};
 
export default App;

主要修改下UI文案,區分本地版本和熱更新版本。

2.4.2.  打包Android產物

在工程的根目錄輸入如下命令進行打包:

react-native bundle --entry-file ./index.js --bundle-output ./bundle/androidBundle/index.android.bundle --platform android --assets-dest ./bundle/androidBundle --dev false 

執行後,工程根目錄/bundle/androidBundle下會生成Android產物,全選androidBundle下所有文件後進行壓縮,得到的zip文件將用於上傳到shiply。
 

2.4.3.  打包iOS產物

在工程的根目錄輸入如下命令進行打包:

react-native bundle --entry-file ./index.js --bundle-output ./bundle/iOSBundle/index.ios.bundle --platform ios --assets-dest ./bundle/iOSBundle --dev false 

執行後,工程根目錄/bundle/iOSBundle下會生成iOS產物,全選iOSBundle下所有文件後進行壓縮,得到的zip文件將用於上傳到shiply。
 
 

2.5.  發佈RN動態化產物

參考3中的發佈平台使用指引,上傳2.4中的zip文件生成發佈任務:
 
 
還原測試代碼,在Demo Android目錄執行./gradlew app:assembleRelease編譯release apk,安裝後運行九能拉到遠端的RN產物了。
這裏按鈕和彈框都是shiply sdk提供的默認UI,也可以參考SDK中的HotUpdateButton 和HotUpdateHelper來自定義UI和請求時機。
 
安裝加載成功後,shiply前端頁面可以看到相關的數據上報。
 

2.6.  小結

總體體驗下來接入比較順暢,花個半天時間就能正常接入shiply rn熱更新。因為CodePush下架急需替代方案的開發者可以考慮接入試用下。

3.  參考文檔

 
Shiply ReactNative 動態化 SDK 接入指引 | Shiply 專業版
ReactNative 動態化發佈平台使用指引 | Shiply 專業版

Add a new 評論

Some HTML is okay.