1. 分包的核心概念
- 主包:包含小程序启动页面(如首页)和公共代码(如全局组件、工具类库等)。
- 分包:开发者划分的独立功能模块,按需加载。例如:商品详情页、用户中心等。
- 体积限制:
- 主包大小不超过 2MB(微信小程序)。
- 所有分包总大小不超过 20MB(微信小程序)。
- 分包可以独立配置(如支付宝小程序的分包策略可能略有不同)。
2. 分包配置方法
在 app.json
中通过 subpackages
(或 subPackages
)字段配置分包:
{
"pages": [
"pages/index/index", // 主包页面
"pages/logs/logs"
],
"subpackages": [
{
"root": "packageA", // 分包根目录
"name": "sub1", // 分包别名(可选)
"pages": [ // 分包页面路径
"pages/cart/cart",
"pages/detail/detail"
],
"independent": false // 是否为独立分包(默认false)
},
{
"root": "packageB",
"pages": ["pages/user/user"]
}
]
}
3. 独立分包
- 特点:独立分包可单独运行,不依赖主包代码(主包不会自动下载)。
- 适用场景:广告页、活动页等需要快速打开的页面。
- 配置:设置
"independent": true
。 - 限制:独立分包内不能引用主包资源(如组件、JS 文件)。
4. 分包预加载
通过 preloadRule
配置在进入特定页面时预加载分包,减少用户等待时间:
{
"preloadRule": {
"pages/index/index": { // 触发预加载的页面路径
"network": "wifi", // 网络条件(可选:wifi/all)
"packages": ["packageA"] // 需要预加载的分包名或 root
}
}
}
5. 注意事项
- 资源引用规则:
- 主包无法直接引用分包中的资源(图片、组件、JS 等)。
- 分包之间不能互相引用资源。
- 公共资源需放在主包中(如通用组件、工具函数)。
- 路由跳转:
- 主包跳转到分包页面:
wx.navigateTo({ url: '/packageA/pages/cart/cart' })
。 - 分包跳转到主包页面:路径需写完整,如
/pages/index/index
。
- 主包跳转到分包页面:
- 体积优化:
- 使用小程序开发者工具的「代码分析」功能检查包体积。
- 压缩图片、移除未使用代码,将非必要资源放到 CDN。
6. 常见问题
- 分包后体积超限:
- 检查主包是否包含过多公共代码,可抽离到分包或使用
npm
管理。 - 使用
webpack
或gulp
进行代码压缩和 Tree Shaking。
- 检查主包是否包含过多公共代码,可抽离到分包或使用
- 页面白屏或资源加载失败:
- 确认资源路径是否正确,避免跨包引用。
- 检查分包配置的
root
和pages
路径是否有效。
- 分包预加载不生效:
- 确保网络环境符合条件(如配置了
"network": "wifi"
但当前是 4G)。 - 检查分包名称或
root
是否拼写错误。
- 确保网络环境符合条件(如配置了
7. 跨平台差异
不同小程序平台的分包策略可能略有不同:
- 微信小程序:支持独立分包和预加载。
- 支付宝小程序:分包配置字段为
subPackages
,总包限制为 8MB。 - 百度/字节跳动小程序:类似微信,需参考具体文档。
通过合理使用分包,可以有效控制小程序体积,提升加载速度和用户体验。建议在开发初期规划好功能模块的分包策略,避免后期重构成本。
8.主包引用分包的数据
在小程序开发中,主包无法直接引用分包的 JS 文件(包括组件、工具函数等),这是由小程序的分包机制决定的。分包的代码在用户访问对应功能时才会加载,而主包的代码在启动时就必须加载完成,因此两者之间存在隔离性。
若需要在主包和分包之间共享逻辑或数据,可通过以下方式间接实现:
1. 公共代码提取到主包
-
适用场景:主包和分包都需要使用的工具函数、公共配置、全局状态等。
-
方法:
将公共代码(如utils/common.js
)放置在主包目录中,主包和分包均可通过相对路径或绝对路径引用:// 主包和分包均可引用 const common = require('../../utils/common.js');
2. 全局变量(App 对象)
-
适用场景:共享简单的全局数据或方法。
-
方法:
在app.js
中定义全局变量或方法,主包和分包均可通过getApp()
访问:// app.js App({ globalData: { version: '1.0.0' }, commonMethod() { /* ... */ } }); // 分包中调用 const app = getApp(); console.log(app.globalData.version); app.commonMethod();
3. 事件通信机制
-
适用场景:主包与分包需要触发特定行为或传递数据。
-
方法:
使用小程序的全局事件监听/触发(如EventChannel
或自定义事件总线):// 主包触发事件 const eventChannel = this.getOpenerEventChannel(); eventChannel.emit('updateData', { data: 'from main' }); // 分包监听事件 const eventChannel = this.getOpenerEventChannel(); eventChannel.on('updateData', (data) => { console.log(data); // { data: 'from main' } });
4. 数据缓存(Storage)
-
适用场景:持久化存储共享数据(如用户 Token)。
-
方法:
通过wx.setStorageSync
和wx.getStorageSync
读写数据:// 主包写入 wx.setStorageSync('token', 'abc123'); // 分包读取 const token = wx.getStorageSync('token');
错误示例
直接跨包引用 JS 文件会导致报错:
// ❌ 错误!主包中尝试引用分包的 JS
const subModule = require('/packageA/utils/sub-module.js');
最佳实践
- 提前规划代码结构:开发初期将公共代码明确划分到主包。
- 避免跨包依赖:分包应尽量独立,减少与主包的耦合。
- 使用 npm 包:将复用性高的代码发布为 npm 包,主包和分包均可安装依赖。
总结
小程序的分包机制强制隔离了主包和分包的代码,目的是保证主包体积最小化。若强行突破限制(如动态加载代码),可能违反小程序的安全规范。合理设计代码结构,遵循官方规则,才能确保小程序顺利发布和运行。