在自己上手实现拆包工具之前,我们也调研了其他家关于这方面的解决方案。
因为这种操作并没有官方的解决方案,又和各家的工程结构相关联,所以网上大家提供的解决方案基本都是描述了实现思路而没有可以直接使用的工具, 而且一般时间也比较久远。
分析了多个案例之后,解决方案基本汇一下两种。
方案一
RN分包之Bundle改造
此篇详细解释了 bundle 文件结构以及如何改造打包工具并且已开源(bundle 文件结构图片来源地)。
整体的实现思路是一致的,但是尝试过之后没有采用,主要原因是:
- 我们的工程采用 TypeScript 开发。在 rn 的工程会有一个 rn.config.js 的配置文件。 这个方案没有去读取这个配置文件,导致 ts/tsx 的代码不支持编译。
- 这个方案是基于 metro 0.20 版本修改的。我们的工程创建时默认使用的是 metro 0.30.+, 这个 metro 工程结构已经发生了很大的变化。
- 它里面采用固定 moduleId 的方案是使用 modulePath 的 md5 值。这有一个问题是整个 metro 和 client 涉及到 moduleId 的部分都是采用 number 类型读取,更改了 moduleId 类型会涉及到很多很多地方的兼容问题。
方案二
这个方案的解决思路非常有意思, 不涉及到任何对 Metro 的修改。
它的主要原理是:
- 调用官方 bundle 构建打包生成 jsbundle
- 调用 babylon 分析 jsbundle 重新生成语法树
- 深度遍历语法树,根据配置文件判断属于 common 的部分写入到 common.bundle; 属于业务的部分写入到 biz.bundle
这个方案的接入成本很低,也很好维护。但是因为没有把 moduleId 固化下来,如果新增一个 module 可能导致很多 module 对应的 id 发生变化,那么所有的线上模块都需要重新部署,运维成本会很高。
结论
以上两个方案是找到有代码可以研究的方案,但是都并不适用于我们现有的工程环境。但是从这个两个方案可以反映出我们的思路是正确的。