React Native 热更新 CodePush

FreeGuideOnline 14阅读 2026-07-11

什么是 CodePush 与热更新

CodePush 是微软提供的一项云服务,专门为 React Native 和 Cordova 应用提供热更新能力。它允许开发者直接向用户终端推送 JavaScript 资源包、图片等静态资源的更新,而无需经过应用商店的漫长审核周期,从而快速修复缺陷或发布新功能。

热更新仅适用于 JavaScript 代码、资源文件(图片、字体等)和部分原生模块 的更新。对于原生代码(如 Java/Kotlin、Objective-C/Swift)的变动、新增原生模块依赖、NATIVE_BUILD 环境的改动,仍需要重新打包并通过应用商店发布新版本。

核心优点:

  • 绕过应用商店审核,分钟级到达用户
  • 可选强制更新或静默下载
  • 支持灰度发布、回滚

环境准备与账号配置

安装 App Center CLI

CodePush 现在已经集成到 App Center 中,管理命令通过 appcenter-cli 执行。

npm install -g appcenter-cli

注册并创建应用

  1. 访问 App Center 注册账号(支持 GitHub、Microsoft 等登录)。
  2. 登录 CLI:
    appcenter login
    
  3. 在 App Center 中创建一个新的应用(Add new app),选择 OS: Android/iOSPlatform: React Native
  4. 创建后复制应用密钥(App Secret),后续在终端需要用到。也可以创建两个应用分别对应 Android 和 iOS,方便独立管理版本。

在 React Native 项目中集成 CodePush

安装 SDK

npm install --save react-native-code-push
cd ios && pod install && cd ..

对于 React Native 0.60 及以上版本,自动链接已经完成。如果自动链接失败,可手动链接:

react-native link react-native-code-push

Android 平台配置

  1. android/settings.gradle 中确认已包含:

    include ':react-native-code-push'
    project(':react-native-code-push').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-code-push/android/app')
    
  2. android/app/build.gradle 中确保引入了依赖。

  3. MainApplication.java(或MainApplication.kt)中注册 CodePush 的 ReactNativeHost

    @Override
    protected String getJSBundleFile() {
        return CodePush.getJSBundleFile();
    }
    

    同时在 getPackages 中加入 new CodePush(getResources().getString(R.string.reactNativeCodePush_androidDeploymentKey), getApplicationContext(), BuildConfig.DEBUG)

  4. android/app/src/main/res/values/strings.xml 中添加 deployment key:

    <string moduleConfig="true" name="reactNativeCodePush_androidDeploymentKey">YOUR_ANDROID_DEPLOYMENT_KEY</string>
    

    Deployment Key 可以在 App Center 中对应应用的 “CodePush” 栏目下获取(Production/Staging 环境各有一个 key)。

iOS 平台配置

  1. ios/你的项目名/Info.plist 中添加 CodePushDeploymentKey,值填写 iOS 应用的 deployment key。

    <key>CodePushDeploymentKey</key>
    <string>YOUR_IOS_DEPLOYMENT_KEY</string>
    
  2. 将 App Center 的 URL 配置添加到 Info.plist(可选,用于自定义服务器):

    <key>CodePushServerURL</key>
    <string>https://codepush.appcenter.ms/</string>
    
  3. AppDelegate.m(或AppDelegate.mm)中更新 source URL:

    #import <CodePush/CodePush.h>
    ...
    - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
    {
      #if DEBUG
        return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
      #else
        return [CodePush bundleURL];
      #endif
    }
    

封装更新策略与 UI 提示

App.js(或入口文件)中包裹根组件,并配置更新检查逻辑。

import React, { useEffect } from 'react';
import codePush from 'react-native-code-push';

let codePushOptions = {
  checkFrequency: codePush.CheckFrequency.ON_APP_RESUME,
  installMode: codePush.InstallMode.ON_NEXT_RESUME,
  mandatoryInstallMode: codePush.InstallMode.IMMEDIATE,
  updateDialog: {
    title: "发现新版本",
    optionalUpdateMessage: "有新版本可用,是否立即更新?",
    optionalInstallButtonLabel: "立即更新",
    optionalIgnoreButtonLabel: "稍后",
    mandatoryUpdateMessage: "必须更新才能继续使用",
    mandatoryContinueButtonLabel: "更新",
  },
};

function App() {
  useEffect(() => {
    codePush.sync({
      updateDialog: true, // 显示默认对话框
      installMode: codePush.InstallMode.IMMEDIATE, // 立即安装
    });
  }, []);
  return <RootComponent />;
}

export default codePush(codePushOptions)(App);

常用参数说明:

  • checkFrequency: ON_APP_START 应用启动时检查,ON_APP_RESUME 从后台恢复时检查。
  • installMode: IMMEDIATE 立即安装(需重启应用),ON_NEXT_RESUME 下次从后台切回时安装,ON_NEXT_RESTART 下次冷启动时安装。
  • mandatoryInstallMode: 当发布标记为强制更新时的安装策略。
  • updateDialog: 自定义更新提示框内容。

发布 CodePush 更新

对项目完成修改并测试后,打包 bundle 并发布。

一、打包 JS bundle 和资源文件:

npx react-native bundle \
  --platform android \   # 或 ios
  --entry-file index.js \
  --bundle-output ./release.bundle \
  --dev false \
  --assets-dest ./release

二、使用 App Center CLI 发布:

appcenter codepush release-react \
  -a <owner>/<app-name> \
  -d Production \          # 或 Staging
  -t ">=1.0.0" \           # 目标二进制版本范围
  --description "修复了某个bug"
  • -a 参数格式为 用户名/应用名,可在 App Center 应用总览页找到。
  • -d 指定部署环境,常用 Staging(测试)和 Production(生产)。
  • -t 规定此次更新适用的原生 app 版本范围,例如 1.0.0 表示只针对该版本,>=1.0.0 表示1.0.0及以上版本。

发布成功后,已集成的终端将在下次触发检查时下载并安装更新。

多环境管理

建议创建至少两个 deployment:

  • Staging:用于内部测试,在发布到正式环境前验证更新。
  • Production:面向最终用户。

获取不同环境的 deployment key,并在构建不同环境的原生包时使用对应 key。例如,Android 可以在 buildTypes 中动态替换 key:

buildTypes {
    debug {
        buildConfigField "String", "CODEPUSH_KEY", '"STAGING_KEY"'
    }
    release {
        buildConfigField "String", "CODEPUSH_KEY", '"PRODUCTION_KEY"'
    }
}

版本控制与高级特性

控制目标二进制版本

发布时可通过 -t 参数精确控制更新送达的 native 版本。支持 semver range 语法:

  • 1.0.0 仅1.0.0
  • >=1.0.0 <2.0.0 全部1.x版本
  • * 所有版本

发布后可在 App Center 后台查看每个更新的安装指标。

强制更新

当发布紧急修复时,可标记为 mandatory:

appcenter codepush release-react ... --mandatory true

终端在同步时会采用 mandatoryInstallMode 指定的安装行为(通常为立即安装)。客户端 sync 时可配合自定义 UI 阻止用户继续使用。

回滚与历史记录

  • 回滚:通过 CLI 或后台将某个部署环境回滚到上一版本:
    appcenter codepush rollback -a <owner>/<app> -d Production
    
  • 查看历史
    appcenter codepush deployment history -a <owner>/<app> -d Staging
    

灰度与启动图兼容

对于包含启动页(splash screen)资源的应用,更新后如果资源有变,可能需要冷重启才能看到效果。建议代码中监听更新安装状态,在合适时机提示用户重启,或使用 restartApp 方法。

codePush.sync({
  installMode: codePush.InstallMode.IMMEDIATE,
},
(status) => {
  // 可以通过status监听状态变化
});

常见问题与排查

  1. 更新下载后未生效
    检查 installMode 配置。若为 ON_NEXT_RESUME,需将应用切到后台再回来才会安装。也可以使用 codePush.restartApp() 强制重启。

  2. iOS 热更新闪退
    确保在发布时没有改变原生桥接(native module)调用,或者页面引用了新的原生组件。这类修改必须通过 App Store 发布。

  3. Android release build 不请求更新
    确认 strings.xml 中 deployment key 正确且 getJSBundleFile 已重写。检查 proguard 规则是否保留了 com.microsoft.codepush.react 相关类。

  4. 更新包下载失败
    国内网络可能受限,可考虑私有化部署 CodePush Server(参考 code-push-server 开源项目),然后修改 CodePushServerURL

  5. 命令行提示未登录
    执行 appcenter logout 后重新 appcenter login

通过合理运用 CodePush,你的 React Native 应用将获得敏捷的迭代能力,在紧急修复和体验优化上抢占先机。