CodePush停服后,如何用腾讯Shiply快速实现ReactNative热更新?

发布于:2025-07-08 ⋅ 阅读:(19) ⋅ 点赞:(0)

目录

一、背景

二、Shiply RN热更新接入实战

2.1 创建Shiply项目及产品

2.2 创建RN模块

2.3 接入Shiply RN动态化SDK

2.3.1 创建RN demo

​​​​​​​2.3.2 添加RN层依赖

​​​​​​​2.3.3 添加Android层依赖

2.3.4 添加热更新检查与加载代码

​​​​​​​2.4 打包RN动态化产物

​​​​​​​2.4.1 修改Demo测试代码

​​​​​​​2.4.2 打包Android产物

​​​​​​​2.4.3 打包iOS产物

​​​​​​​2.5 发布RN动态化产物

​​​​​​​2.6 小结

三、参考文档


一、背景

CodePush是微软VisualStudioAppCenter服务的一个子功能支持动态下发RN热更新产物

但是VisualStudioAppCenter 2025/3/31 已经停止服务,如果继续使用CodePush需要自己独立部署。​​​​​​​

专门独立部署一套后台服务对于个人开发尤其客户端开发来说时间成本后期维护也需要投入不少精力最好还是使用已有下发平台

调研一下发现目前PushyShiply平台支持RN热更新

Pushy ReactNative中文网推出RN下发平台支持差量更新CLI网页双端管理

Shiply 腾讯端服务团队推出面向客户端全场景发布平台支持动态下发配置、资源、软件包(App)Android热更新flutter热更新最近上线RN热更新功能

体验下来感觉Shiply前端交互友好完整审批发布流程支持多维度下发规则看到客户端下发加载数据下面详细介绍Shiply RN热更新接入使用过程

二、Shiply RN热更新接入实战

2.1 创建Shiply项目及产品

参考第三点发布平台使用指引创建一个测试项目创建AndroidiOS产品

​​​​​​​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 添加热更新检查加载代码

修改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

​​​​​​​修改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路径。

​​​​​​​修改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路径。

做完以上步骤完成接入Android运行效果如下

这时点击检查更新没有什么效果因为没有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安装运行效果如下

这里按钮弹框都是shiply sdk提供默认UI可以参考SDKHotUpdateButton HotUpdateHelper自定义UI请求时机

安装加载成功shiply前端页面可以看到相关数据上报

​​​​​​​2.6 小结

总体体验下来接入比较顺畅花个半天时间就能正常接入shiply rn热更新因为CodePush下架急需替代方案开发可以考虑接入试用

三、参考文档

Shiply ReactNative 动态化 SDK 接入指引 | Shiply 专业版

ReactNative 动态化发布平台使用指引 | Shiply 专业版


网站公告

今日签到

点亮在社区的每一天
去签到