小程序分包
主包、独立分包、分包:
- 分包的根目录不能是另一个分包的子目录
- tab必须在主包中
- 分包的JS文件不能相互共享,但使用
分包异步化
不受此限制 - 分包可以共享主包的资源(独立分包除外)
/**
app.json
1. app.json文件中,最外层page数组中的页面,既是包仅有一个
2. subpackages数组中的页面,即是容,分包可以有多个
3. 分包中有字段`independent`为true时,即为独立分包,独立分包可以有多个
*/
{
// 主包
"pages":[
"pages/index",
"pages/logs"
],
// 分包
"subpackages": [
// 普通分包
{
"root": "packageA",
"pages": [
"pages/cat",
"pages/dog"
]
},
// 独立分包
{
"root": "packageB",
"name": "pack2",
"pages": [
"pages/apple",
"pages/banana"
],
"independent": true
}
]
}
主包/分包:
- 主包仅能有一个,分包可以有多个
- App只能定义在主包中
- tabbar页面必须在主包中
分包/独立分包:
- 独立分包加载时,可以不下载主包,普通分包加载时需要下载主包
- 独立分包不可以依赖主包内容,包括js、wxss、自定义组件、插件等(使用分包异步化时,js、自定义组件、插件不受此限制)
- 主分包中的app.wxss对独立分包无效,应避免在独立分包中使用
- 独立分包中不支持使用插件
- 独立分包可以调用getApp({allowDefault:true})创建临时App对象
分包预下载:
在app.json中加preloadRule
字段实现预下载包
// app.json
{
"pages": ["pages/index"],
"subpackages": [
{
"root": "important",
"pages": ["index"],
},
{
"root": "sub1",
"pages": ["index"],
},
{
"name": "hello",
"root": "path/to",
"pages": ["index"]
},
{
"root": "sub3",
"pages": ["index"]
},
{
"root": "indep",
"pages": ["index"],
"independent": true
}
],
"preloadRule": {
"pages/index": {
"network": "all",
"packages": ["important"]
},
"sub1/index": {
"packages": ["hello", "sub3"]
},
"sub3/index": {
"packages": ["path/to"]
},
"indep/index": {
"packages": ["__APP__"]
}
}
}
preloadRule
中,key
是页面路径,value
是进入此页面的预下载配置,每个配置有以下几项:
字段 | 类型 | 必填 | 默认值 | 说明 |
---|---|---|---|---|
packages | StringArray | 是 | 无 | 进入页面后预下载分包的 root 或 name 。__APP__ 表示主包。 |
network | String | 否 | wifi | 在指定网络下预下载,可选值为: all : 不限网络 wifi : 仅wifi下预下载 |
跨包资源引用:除了非独立分包可以依赖主包之外,其他分包之前是不能相互引用资源的,但启用分包异步化
功能可实现跨包资源引用。
跨分包组件引用:按需注入+用时注入(占位组件)+分包预加载
// subPackageA/pages/index.json
"pages": ["pages/index"],
"subpackages": [
{
"root": "important",
"pages": ["index"],
},
{
"root": "subPackageB",
"pages": ["index"],
},
],
"lazyCodeLoading": "requiredComponents" // 按需引入
{
"usingComponents": {
"button": "../../commonPackage/components/button",
"list": "../../subPackageB/components/full-list", // 跨包自定义组件
"simple-list": "../components/simple-list",
"plugin-comp": "plugin://pluginInSubPackageB/comp"
},
"componentPlaceholder": {
"button": "view", // 占位组件
"list": "simple-list", // 占位组件
"plugin-comp": "view" // 占位组件
},
// 分包与下载
"preloadRule": {
"pages/index": {
"network": "all",
"packages": ["subPackageB"]
},
}
}
跨分包js引用:
// subPackageA/index.js
// 使用回调函数风格的调用
require('../subPackageB/utils.js', utils => {
console.log(utils.whoami) // Wechat MiniProgram
}, ({mod, errMsg}) => {
console.error(`path: ${mod}, ${errMsg}`)
})
// 或者使用 Promise 风格的调用
require.async('../commonPackage/index.js').then(pkg => {
pkg.getPackageName() // 'common'
}).catch(({mod, errMsg}) => {
console.error(`path: ${mod}, ${errMsg}`)
})
如何规划分包:
- 解决问题:随着功能迭代,项目包体积越来越多,影响小程序性能、甚至超过小程序体积范围2M,出现无法打包、代码上传等问题
- 分包好处:项目有更大的体积,承载更多功能;提升项目性能、用户体验
分包建议:
-
根据功能模块拆分: 将小程序的功能模块拆分成不同的子包。比如:tabbar 模块、用户模块、推送模块等等。
-
根据资源引用拆分: 自定义组件、JS 文件、静态资源仅被一个分包使用时则把它划为同一个分包中,如果是公共的资源被各个分包使用,则将其划为主包。
-
分包预下载配置: 通过分包预下载机制,在用户需要时能够快速加载,配置 preloadRule 后,在进入小程序某个页面时,由框架自动预下载可能需要的分包,提升进入后续分包页面时的启动速度,减少用户等待时间,提升用户体验。
转载自:https://juejin.cn/post/7378143151889072162