WdBly Blog

懂事、有趣、保持理智

WdBly Blog

懂事、有趣、保持理智

周维 | Jim

603927378@qq.com

React Native使用Code Push热更新完整解决方案

本篇文章详细讲解了在React Native中Code Push热更新问题,从环境搭建、热更新流程分析、App热更选泽,后台管理系统等方面给出完整的解决方案

Code Push系列之 - 环境安装

Code Push系列之 - 发布更新

Code Push系列之 - 客户端检查更新

折腾React Native的热更新也有一段时间了,在前段时间还专门写过一篇环境搭建的文章,里面分享了本地开发和热更服务器的环境问题,在这篇文章主要是梳理热更新的流程,会从开发者端热更新发布端热更新服务端App端四个方面进行分析梳理,同时会分享这个过程中涉及到相关问题,包括了热更新的版本号管理发布热更的后台管理系统设计等问题。

在正式分析之前,大家可以先思考下,你期望的热更新系统会达到什么样的效果呢?要发布一次更新流程如何? 系统在完成后,将之交付于业务同事使用,开发人员应尽可能少的去关注它。我司热更的大致流程如下图供大家参考

未命名文件.jpg

一、开发者端

本地环境搭建请参考我的另一篇文章React Native热更新本地环境搭建

每一次的热更发布在开发端总会经历如下过程:

分支管理

每个热更新版本都需要在一个新的分支上开发,同时此分支也是版本开发完成后发布更新的分支,分支名我么遵循如下规则,如:release/20190926_1.8.1.2_newActivity
image.png

  • 20190926 release时间
  • 1.8.1.2 热更版本号
  • newActivity 版本简述

变量替换

在业务完成后,开发者需要打包App交由测试人员测试。热更发布通常需要开发人员提供三种包:

  • QA环境的测试包
  • 线上环境的测试包
  • 线上环境的生产包

所以在每次打包之前,需要执行脚本,根据参数来替换代码中的Key值,如执行npm run build --dev,会将CodePush的key和host指向qa。

打包静态资源

执行react-native bundle命令可以将js代码打包成jsbundle文件,也可将静态文件如图片打包到文件夹中。

react-native bundle --platform ios --entry-file index.js --bundle-output ./bundles/ios/main.jsbundle --assets-dest ./bundles/ios --verbose --dev false

这行命令的作用是 从index.js为入口,将打包的jsbundle输出到./bundles/ios/main.jsbundle文件,将静态文件输出到./bundles/ios目录下, 打包环境为生成环境

这里打包输出的jsbundle最终会上传到code push服务端用于App端对比更新。

在开发端打包静态资源主要是为了节省发布更新的时间,当然总时间是不变的,(优化了发布系统的体验而已)

推送代码

开发者将代码推送到代码服务器。

二、热更新发布端

后台管理系统.jpg

从上图可以看出来,此发布热更系统基本已经包含了所有常用的热更新功能,包括了最常用的releasepatchpromoterollback命令。对热更发布不熟悉的可以参考我整理的常用热更新发布方式,这里主要关注系统的流程和设计。

版本号设计

在热更系统中维护一个版本号,开发者希望这个版本号能够反映出对应的二进制包的版本如2.2.0,同时亦能对应到热更的版本号。

在code push的服务端执行code-push deployment ls appName能查看到如下部署信息
image.png

显然这个V9版本号不能满足目前的需求,需要自己设计一套版本号规则,同时和这个V9对应起来。

最终的版本号 = 二进制版本号 + 热更新版本号,如这版热更是针对1.8.1版本的二进制包发布的第三个热更版本,则最终版本号为1.8.1.3

在App内部通过维护此版本号帮助快速定位版本问题version = 1.8.1.3,同时会在个人中心展示此版本号,同时在接口中带上此版本号。

版本号对应

上面设计了一个新的版本号来代替code push提供的V9,但是最终还是需要为这两个版本号建立对应关系,才能保证系统的正常运行,比如需要回滚某个有严重bug1.9.0.5版本到1.9.0.4,最终需要执行

code-push rollback MyApp Production --targetRelease v34

这里需要建立1.9.0.4v34版本的一一对应。

新建version_control数据表存储此关系。

每次发布新版的热更新时,运营人员只需要选泽热更的二机制的版本即可1.8.0,后续的最终版本号由系统按照热更版本自动加一的规则自动生成。

查看发布历史

运营人员通过版本号等条件可以查看发布历史信息,版本历史相关数据如下:

{ description: '', isDisabled: false, isMandatory: false, rollout: 100, appVersion: '1.8.0', packageHash: '0e616848b4ac4f77617fe51d2c7271dfdde1cad2fa478b2d2b75c6f9d274ae02', blobUrl: 'http://192.168.1.1:3000/download/fj/Fji6Hx1buh-sd7f6o9x2BtCLv4MT', size: 1656590, manifestBlobUrl: 'http://192.168.1.1:3000/download/fs/FswRb5CD9YCbMjzdyQ3EQYI7QUC7', diffPackageMap: null, releaseMethod: 'Upload', uploadTime: 1567362630000, originalLabel: '', originalDeployment: '', label: 'v5' }

这节介绍了热更发布的管理后台,下节介绍发布服务端的接口功能。

三、热更新服务端

热更发布服务端使用了code push提供了Node.js的CodePush Management SDK

CodePush Management SDK是一个JavaScript库,用于以编程方式管理CodePush帐户,该库允许编写基于Node.js的构建和/或部署脚本,而无需使用CLI。

部署流程.jpg

基于CodePush Management SDK搭建一个node的Http服务,为热更新发布后台管理系统提供服务。
使用示例:

npm i code-push -S
var CodePush = require("code-push"); var codePush = new CodePush("YOU_ACCESS_KEY", null, "YOUR_CODE_PUSH_HOST"); /** * 获取历史部署 * @param {string} appName * @param {string} deploymentName */ async function getDeploymentHistory(appName, deploymentName) { let rs = await codePush.getDeploymentHistory(appName, deploymentName); console.log(rs); } getDeploymentHistory("YOUR_APP_NAME", "Production")

通过上方代码就可以直接使用此服务了,这里说以下很坑的点。

在官方文档中YOU_ACCESS_KEY的值是通过code-push access-key add "YOU_ACCESS_KEY"来的,但通过实验发现此key无效。并输出错误401 Unauthorized

解决:执行cat ~/.code-push.config,使用输出的accessKey作为YOU_ACCESS_KEY

继续执行还是输出了错误:
The session or access key being used is invalid; please run “code-push login” again. If you are on an older version of the CLI, you may need to run “code-push logout” first to clear the session cache.

这个问题我在github上查了很久都没有答案,最后翻看源码终于发现了问题所在,CodePush构造函数的第三个参数接收的是你的codepush服务所在的地址,国内的环境想要使用微软的code-push云服务也会有很多问题。所以都在自己的服务器上搭建,所以会遇到此问题,而国外的程序员一般来说都是使用微软提供的云服务所以没有碰到相关问题,所以在使用时给第三个参数传入自己code push地址即可。

new CodePush("test", null, "http://127.0.0.1:3000")

具体这个基于node的服务如何搭建取决于你们公司的实际情况而定。

四、App端

目前设计为用户每次打开App时都会去检查又无可用更新,若是有可用更新则静默下载,待下次启动App时安装更新。这样的好处是整个更新过程用于是无感的。

code-push的热更模式有多个,涉及的方法和属性也有很多,详情请参考这篇code push App检查更新方法

总结

开发者端热更新发布端热更新服务端App端分析了Code Push的热更流程,以及每个环节应该做什么事情,这其中涉及到的点主要有:

  • 开发环境搭建和发布前准备
  • 热更新版本号的设计和对应关系
  • 依赖于CodePush Management SDK的发布系统设计
  • App端采用的更新模式选则

还差什么?

  • 监控很报警系统(大面积更新失败等严重问题)