react-native-multibundler分包加载(转载)

213次阅读
没有评论

共计 5121 个字符,预计需要花费 13 分钟才能阅读完成。

react-native-multibundler

原地址
基于 react native 的 metro bundler 的配置化开发来处理分包,支持 iOS 和 Android,支持远程加载,metro bundler 为官方打包的工具,使用官方分包方法更灵活稳定,比网上的一些方法更实用可靠。

支持 debug、可选模块路径或者递增 id 作为模块 id

metro 官方:https://facebook.github.io/metro/

支持 react native 0.57~0.63.2,由于采用的是官方 metro 拆包,理论上日后的 rn 版本无需修改就能兼容

iOS 和 Android 都有加载多 bundle 实例,经测试稳定可靠

demo 使用说明:

 1、进入项目文件夹:npm install

 2、android:使用 android studio 打开 android 项目 iOS:使用 xcode 打开 iOS 项目

 3、直接运行 android 或 iOS 项目,jsbundle 包已经事先打好 

react-native-multibundler 分包加载(转载)
react-native-multibundler 分包加载(转载)

如何接入原有项目:

android

1、拷贝除了 demo 文件夹下的所有代码文件到项目

2、根据自己的需要自定义 platformDep.js 和 platform57.config.js,这里确定基础包包含的 js module

3、根据自己的需要确定你的业务入口 js 和 buz57.config.js,这里确定业务包包含的 js 代码

4、打包:根据底下给出的打包命令打包

5、业务的 UI 入口使用继承自 AsyncReactActivity 的 activity,重写 getScriptPath 和 getScriptPathType 确定业务 bundle 路径,重写 getMainComponentName 确定加载的业务 module

6、根据需要事先加载基础包,如果没有事先加载基础包,AsyncReactActivity 会自动加载,加载基础包代码如下

ReactInstanceManager reactInstanceManager = ((ReactApplication)getApplication()).getReactNativeHost().getReactInstanceManager();
    reactInstanceManager.createReactContextInBackground();// 这里会先加载基础包 platform.android.bundle,也可以不加载

7、重写 ReactApplication 返回基础包的位置 

iOS

1、暴露 RCTBridge 的 executeSourceCode 方法,做法为将本项目中的 RCTBridge 添加到自己的工程

2~4、与 android 的做法一样,见上方

5、事先加载基础包:jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"platform.ios" withExtension:@"bundle"];
bridge = [[RCTBridge alloc] initWithBundleURL:jsCodeLocation
                             moduleProvider:nil
                              launchOptions:launchOptions];

6、加载业务包:NSURL *jsCodeLocationBuz = [[NSBundle mainBundle] URLForResource:bundleName withExtension:@"bundle"];
  NSError *error = nil;
  NSData *sourceBuz = [NSData dataWithContentsOfFile:jsCodeLocationBuz.path
                                         options:NSDataReadingMappedIfSafe
                                           error:&error];
  [bridge.batchedBridge executeSourceCode:sourceBuz sync:NO];

7、创建 RCTRootView,并绑定业务代码

RCTRootView* view = [[RCTRootView alloc] initWithBridge:bridge moduleName:moduleName initialProperties:nil];

DEBUG

 从 2.1 版本之后加入了 debug 调试功能,主要工作原理:将需要 debug 的业务模块代码复制到 debug 入口文件 MultiDebugEntry.js 中,然后在原生端加载该入口文件来调试;使用步骤:1、配置需要调试的业务入口文件 DegbugBuzEntrys.json,在这个 json 数组中加入业务入口 js 文件相对主工程的相对路径
2、在 Android 中的 ScriptLoadUtil.java 中的 MULTI_DEBUG 变量设置成 true,或者在 iOS 中将 MULTI_DEBUG 设置为 true
3、主工程目录下执行:node multiDebug.js
4、启动你的原生 app,开始调试

模块 ID

 从 2.2 版本之后加入了递增 index 作为模块 id 的选项。使用步骤:1、该选项的开关在 getModulelId.js 文件中的 useIndex,设置为 true 就能开启递增 index 作为 moduleId 的功能
2、配置 ModuleIdConfig.json 文件,格式为 入口文件 js: 起始的 moduleId,如下:{
  "index.js":100000,
  "index2.js":200000,
  "index3.js":300000
}
基础包的 moduleId 是固定从 0 开始,因此业务包的 moduleId 起始值建议从 100000 开始,以防止和基础重复
不同业务包的起始 moduleId 也要避免重复
3、执行打包命令或者使用 UI 打包,multibundler 目录下会生成 platformMap.json、indexMap.json 等模块对应的 ID 映射表,用于后续模块 id 增量打包
使用递增 index 作为 moduleId 的好处:1、比路径名作为 moduleId 更短,减小包大小
2、打包后模块名得到保护
3、可以使用 debug 模式打包,即打包命令中 --dev 可以为 true, 方便调试

远程 bundle 加载

 从 v3.0 之后加入了远程的 bundle 加载功能。使用步骤:1、打包远程包,远程包是一个 zip 压缩包,打包命令和普通的业务包的打包命令一致,最好修改保存 bundle 和 assets 的目录,这样压缩的时候直接在专门的目录压缩,打包后需自己手动将 bundle 压缩,压缩时要把 bundle 文件和 assets 放在第一级 (即压缩包内不要有上层目录)
2、把压缩的 zip 包放在网络上,重写 AsyncReactActivity(Android) 或者创建一个 ReactController 对象 (iOS),指定加载类型为 network,并指定链接、模块名、bundle 名
3、启动这个 Activity 或者 Controller 就能将远程的业务包加载成功
友情提示:1、该功能顺便把 " 不同业务包放在不同目录下的需求 " 给解决了,这个也归功于新的 react-native-smartassets
2、远程的 bundle 加载功能并没有做 md5 校验,这个需要开发者自己解决,主要由于 md5 主要还是需要服务端返回的信息,作为通用的拆包开源项目不会提供 md5 校验
3、rn 0.62 版本经测试会出现爆红的问题,主要是因为新增的 LogBox 模块擅自 runApplication 导致崩溃,最新的 RN 版本 0.63 已经没有该问题

js 项目结构:

.
├── App.js               业务界面 1
├── App2.js              业务界面 2
├── App3.js              业务界面 3
├── LICENSE
├── README.md
├── android              android 项目目录
├── app.json 
├── buzDep.json        UI 打包中,打业务包的中间产物,这里面包含的是当前业务包的依赖
├── buz.config.js      业务包的打包配置
├── buz-ui.config.js     UI 打业务包配置
├── index.js             业务 1 入口 js
├── index2.js            业务 2 入口 js
├── index3.js            业务 3 入口 js
├── ios ios 目录
├── multibundler         包含着 debug 配置和公用方法模块
├── multiDebug.js        debug node 命令行工具
├── multiDebugEntry.js   debug 生成的 rn 调试入口,里面拼接着需要调试模块的入口代码     
├── multibundler_cmd.txt 打包命令
├── package.json
├── platform-ui.config.js UI 打基础包配置
├── platformDep-ui.js    UI 打基础包入口
├── platform.config.js 基础包打包配置
├── platformDep.js       基础包打包入口
├── platform-import.js   UI 打包中生成的基础包依赖的模块 import 代码
└── platformDep.json     UI 打包中生成的基础包所依赖模块的配置文件 

android 目录结构

.
├── AndroidManifest.xml
├── assets
│   ├── index.android.bundle   业务包
│   ├── index2.android.bundle  
│   └── platform.android.bundle 基础包
└── java
    └── com
        ├── facebook
        │   └── react
        │       ├── AsyncReactActivity.java 重要!rn 业务加载入口,业务 activity 重写该类
        │       ├── ReactUtil.java
        │       └── bridge
        └── reactnative_multibundler
            ├── FileUtils.java
            ├── ScriptLoadUtil.java
            └── demo   demo 目录,集成项目可删除
                ├── Buz1Activity.java
                ├── Buz2Activity.java
                ├── MainActivity.java
                └── MainApplication.java

UI 打包 (现在支持 mac os,windows):

 使用方式:下载 https://github.com/smallnew/RN-MultiBundler-UI,并根据项目中的 readme 来运行
 选择打包选项后点击打包, 该方法可代替命令打包并帮助计算业务包依赖并去重 

react-native-multibundler 分包加载(转载)

打包命令如下:

android

打 android 基础包

node ./node_modules/react-native/local-cli/cli.js bundle –platform android –dev false –entry-file platformDep.js –bundle-output ./android/app/src/main/assets/platform.android.bundle –assets-dest android/app/src/main/res/ –config /{你的绝对路径}/platform.config.js

打 android 业务包

node ./node_modules/react-native/local-cli/cli.js bundle –platform android –dev false –entry-file index.js –bundle-output ./android/app/src/main/assets/index.android.bundle –assets-dest android/app/src/main/res/ –config /{你的绝对路径}/buz.config.js

iOS

打 iOS 基础包

node ./node_modules/react-native/local-cli/cli.js bundle –platform ios –dev false –entry-file platformDep.js –bundle-output ./ios/platform.ios.bundle –assets-dest ./ios/ –config /{你的绝对路径}/platform.config.js

打 iOS 业务包

node ./node_modules/react-native/local-cli/cli.js bundle –platform ios –dev false –entry-file index.js –bundle-output ./ios/index.ios.bundle –assets-dest ./ios/ –config /{你的绝对路径}/buz.config.js

正文完
 2
评论(没有评论)