react-native-code-push非首次热更bundle增量

3,509 阅读2分钟

前言

code-push在首次热更的时候会全量下载,为后面的资源增量热更做准备。这里注意的是它只是资源文件进行增量,bundle文件并不会,现今bundle文件越来越大的时候bundle文件增量也是一个不错的优化空间。

前置条件

使用code-push-server搭建热更服务

链接远程数据库在 codepush apps表中修改 is_use_diff_text 为1 具体操作在热更新code-push-server小白一步步手动搭建有说明

原生端使用google diff-match-patch处理合并

Android客户端适配,需要合并PR1393

iOS客户端适配,需要合并PR 1399

当然可以直接使用

"react-native-code-push": "git+https://git@github.com/lisong/react-native-code-push.git"

// react-native 0.62版本可以使用(如果没有合适自己版本的可以自己fork根据上面2个PR进行修改)
"react-native-code-push": "https://github.com/syanbo/react-native-code-push/archive/v6.2.0-beta.1.tar.gz"

注意

关于react.gradle

apply from: "../../node_modules/react-native/react.gradle"

这个插件主要做了2件事件

  • bundle${targetName}JsAndAssets 同样的调用了node 脚本 react-native bundle 进行打包。

  • copy${targetName}BundledJs 对打包产物进行拷贝Android项目在构建过程中mergeAssets的时候,会将该目录下的bundle文件打包到assets目录下。

如果安卓打包使用的是react-native bundle自定义,不用依赖react.gradle

关于codepush.gradle

apply from: "../../node_modules/react-native-code-push/android/codepush.gradle"

它也做了2件事情

  • 记录apk文件的构建时间
resValue 'string', "CODE_PUSH_APK_BUILD_TIME", String.format("\"%d\"", System.currentTimeMillis())
  • 生成CodePushHash
// node脚本generateBundledResourcesHash 参数是react.gradle 生成的资源路径
commandLine (*nodeExecutableAndArgs, "${nodeModulesPath}/react-native-code-push/scripts/generateBundledResourcesHash.js", resourcesDir, jsBundleFile, jsBundleDir)

Android react-native bundle自定义打包处理(没有自定义的跳过)

  • 移除上面2个gradle插件在原生的引入

  • 在buildTypes对应的环境中加入CODE_PUSH_APK_BUILD_TIME

buildTypes {
        debug {
           resValue 'string', "CODE_PUSH_APK_BUILD_TIME", String.format("\"%d\"", System.currentTimeMillis())
        }
        ...
        release {
            resValue 'string', "CODE_PUSH_APK_BUILD_TIME", String.format("\"%d\"", System.currentTimeMillis())
        }
    }
  • react-native bundle打包完成,传入对应路径参数调用generateBundledResourcesHash脚本
echo "------------------------ 安装 node_modules 依赖  ------------------------"
yarn

echo "------------------------ 清除旧 RN Bundle 资源 ------------------------"

# 因为每次打的 RN 包的 Assets 是替换之前,所以对于废弃的图片可能依然存在其中;
# 所以每次打 RN 包之前进行清除。
PUSH_DIR="./CodePush"
if [ -d "$PUSH_DIR" ];then
  rm -rf $PUSH_DIR
fi
mkdir $PUSH_DIR
find $PUSH_DIR -name .DS_Store | xargs rm -rf

echo "------------------------ 生成新 Android RN Bundle 资源 ------------------------"
npx react-native bundle --reset-cache --entry-file index.js --bundle-output $PUSH_DIR/index.android.bundle --platform android --assets-dest $PUSH_DIR --dev false

echo "------------------------ 开始生成 CodePushHash 文件 ------------------------"
PUSH_PWD="$(pwd)/CodePush"
node ./node_modules/@lyg-react-native/code-push/scripts/generateBundledResourcesHash.js "$PUSH_PWD" "$PUSH_PWD/index.android.bundle" "$PUSH_PWD"

mkdir "$(pwd)/android/src/main/assets"

cp -r "${PUSH_PWD}/assets" $(pwd)/android/src/main
cp -r "${PUSH_PWD}/index.android.bundle" "$(pwd)/android/src/main/assets"
cp -r "${PUSH_PWD}/CodePushHash" "$(pwd)/android/src/main/assets"
cp -r "${PUSH_PWD}/raw" "$(pwd)/android/src/main/res"
cp -r "${PUSH_PWD}/drawable-hdpi" "$(pwd)/android/src/main/res"
cp -r "${PUSH_PWD}/drawable-mdpi" "$(pwd)/android/src/main/res"
cp -r "${PUSH_PWD}/drawable-xhdpi" "$(pwd)/android/src/main/res"
cp -r "${PUSH_PWD}/drawable-xxhdpi" "$(pwd)/android/src/main/res"
cp -r "${PUSH_PWD}/drawable-xxxhdpi" "$(pwd)/android/src/main/res"

echo -e "\n•••••••••••••••••••••••• Android 执行完毕 ••••••••••••••••••••••••\n"

开始热更新

  • 正常热更新操作

  • 第二次热更时你会发现多了一个hotcodepush.json文件

{"deletedFiles":[],"patchedFiles":["CodePush/index.android.bundle"]}
  • 还有index.android.bundle很小很小

  • 在非首次触发热更的时候将会特别快,大大减少了由于网络环境问题导致热更新失败,并且能快速响应热更新的结果,解决紧急bug尤为重要。

合集

react-native-code-push首次增量热更优化

react-native-code-push非首次热更bundle增量

参考

CodePush支持多包——加载不同业务的bundle包