react native 热更原理

作者: 马六甲的笔记 | 来源:发表于2019-10-08 10:55 被阅读0次

一、原理

  1. RN 打包后,会在 apk 或 ipa 中生成一个 jsBundle 文件,作为默认载入的文件,但同时预留了自定义 jsBundle 路径的接口,这也就给热更提供了基本的环境支持

android

public class MainApplication extends Application implements ReactApplication {

  private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
   ....
    @Override
    protected String getJSBundleFile() {
        return "JSBundlePath"
    }
    ...
  }
}

iOS

- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#if DEBUG
  return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
#else
  return "JSBundlePath"
#endif
}
  1. RN 同时提供了 react-native bundle 这样的命令来生成 jsBundle 文件,这样想办法自更新 JSBundlePath 文件就能实现热更了

  2. 值得注意的是,这种热更只能更新动态文件,即 jsx 和 jsx 引用资源,对于需要包里面的其他模块,如原生模块是没有办法的

二、参考

react-native-pushy 为例子,只讲原理,不涉及代码

  1. 提供一个函数来计算 jsBundle,files 目录 > 默认目录,即默认目录作为 fallback

  2. 下载更新

以当前版本作为参数,请求服务器,返回

 {
        update: true,
        name: '1.0.3-rc',
        hash: 'hash',
        description: '添加聊天功能\n修复商城页面BUG',
        metaInfo: '{"silent":true}',
        updateUrl: 'http://update-packages.reactnative.cn/hash',
        pdiffUrl: 'http://update-packages.reactnative.cn/hash',
        diffUrl: 'http://update-packages.reactnative.cn/hash',
    }

根据返回的信息,下载新的 jsBundle 保存到 files 目录,这样就完成了热更

  1. 主要说一下 react-native-pushy 的增量更新功能,这是一个非常有用的功能,rn 的 jsBundle 哪怕只是一个 jsx 编译得到的,也有个 几百K, 稍微开发一下,可能就是 几M 了,根据实际情况,可能会更大。

react-native-pushy 实现增量更新的思路

diffUrl 最新版本 与 前一个版本的 增量,比如最新为 1.0.6, 用户当前的版本刚好为 1.0.5,那么就可以使用这个增量进行更新,即合并增量文件到 1.0.5 jsBundle 上作为 1.0.6 的 jsBundle

pdiffUrl 最新版本 与 初始版本的 增量,若当前用户安装后就没更新过,或者只更新到了 1.0.3,将增量合并到初始安装包 jsBundle 上 作为 1.0.6 的 jsBundle

updateUrl 完整的 1.0.6 文件,可全量下载,作为新的 jsBundle

最小化更新肯定是 diffUrl,跨版本更新则使用相对于初始包的增量包 pdiffUrl,其实也可以计算任意两个版本的增量,生成增量包,但这样,版本数量多的话,增量包就太多了。

react-native-pushy 使用了 bsdiff 作为增量更新工具,该工具提供了 bsdiffbspatch 两个方法,使用 bsdiff 方法在服务端生成增量包,客户端下载增量包后,使用 bspatch 进行合并。

相关文章

网友评论

    本文标题:react native 热更原理

    本文链接:https://www.haomeiwen.com/subject/blmspctx.html