分包指的是把一个完整的小程序项目,按照需求划分为不同的子包,在构建时打包成不同的分包,用户在使用时可以按照需求进行加载。分包对于开发团队来说可以更好的解耦协作,对于用户来说可以优化小程序首次启动的下载时间。
另对于微信小程序来说,是对项目大小有限制的。在开发工具的详情 => 项目配置中可以看到,不使用分包时总大小只能有 2M ,使用分包时每个分包大小为 2M ,总大小为 20M(网上有些说是16M,具体的可以查看自己的项目配置) ,所以当项目大小到一定程度后,必须进行分包。
分包前后的项目构成
分包前所有的页面和资源是打包到一起的,使用时全部下载到本地。而分包后项目由一个主包和若干个分包组成。
- 主包:一般只包含项目的启动页面或 TabBar 页面,以及所有分包都需要使用到的公共资源。
- 分包:只包含和当前分包有关的页面和私有资源。
分包的加载规则
小程序启动时,会按照一下规则进行加载:
- 首先默认下载主包,并启动主包内的页面
tabBar 页面需要放到主包中
- 当用户进入到分包内的页面时,客户端会下载相应的分包,下载完再进行展示。
非 tabBar 页面可以按照功能的不同,划分为不同的分包之后,按需下载。
文件分配
一般分包后小程序项目的目录结构分为4部分:
- 包含 app.js 、app.json 、app.wxss 在内的应用全局代码
- pages 文件夹,存放主包的所有页面
- 若干自定义的分包文件夹,用于存放分包的页面
- 包括 utils 等存放公共资源文件的文件夹
所以主包就包括了1、2、4项所包含的文件,而第3项则是分包文件。
分包的配置定义
分包在 app.json 中进行定义。类似于主包页面在 app.json 里的 pages 节点中被定义,分包在 app.json 里同一级别的 subpackages 节点中被定义。 subpackages 定义的是个对象数组,每个对象成员就是一个分包,其包含4个字段:
字段 |
类型 |
说明 |
root |
String |
分包的根目录 |
name |
String |
分包的别名,分包预下载时使用 |
pages |
String Array |
分包页面路径,相对于分包根目录 |
independent |
Boolean |
是否独立分包 |
分包的一些原则
打包原则
- 声明 subpackages 后,将按 subpackages 配置路径进行打包,subpackages 配置路径外的目录将被打包到主包中
- 主包也可以有自己的 pages,即最外层的 pages 字段
- subpackage 的根目录不能是另外一个 subpackage 内的子目录,即不能互相嵌套
- tabBar 页面必须在主包内
引用原则
- 主包无法引用分包内的私有资源
- 分包之间不能相互引用私有资源
- 分包可以引用主包内的公共资源
分包举例
使用以下目录结构进行举例
├── app.js
├── app.json
├── app.wxss
├── packageA
│ └── pages
│ ├── cat
│ └── dog
├── packageB
│ └── pages
│ ├── apple
│ └── banana
├── pages
│ ├── index
│ └── logs
└── utils
则分包的配置代码为:
{
"pages":[ // 主包页面
"pages/index",
"pages/logs"
],
"subpackages": [
{ // 分包1
"root": "packageA",
"pages": [
"pages/cat",
"pages/dog"
]
}, { // 分包2
"root": "packageB",
"name": "pack2",
"pages": [
"pages/apple",
"pages/banana"
]
}
]
}
独立分包
独立分包是一种特殊类型的分包,可以独立于主包和其他分包单独运行。通常用户会从主包进入小程序,但是特殊情况时从独立分包中页面进入小程序,不需要下载主包。当用户进入普通分包或主包内页面时,主包才会被下载。因此独立分包和主包以及其他分包之间是相互隔离的。
独立分包的应用场景举例
在以往程序中,普通用户和管理员用户所访问的页面是完全不同的。在小程序中,就可以将管理员页面作为独立分包,能够大幅提升分包页面的启动速度。 一个小程序中可以有多个独立分包,以应对不同场景。
声明独立分包
在分包的 subpackages 字段中,使用 "independent": true
来声明此分包为独立分包。
进入独立分包页面
因为小程序的默认进入页面是 pages 配置的第一个页面,所以直接打开小程序时是需要加载主包的。进入独立分包页面而不加载主包的场景从网上搜索的结果看来,应该是通过其他方式跳转路径打开而绕过主包。猜想是类似通过其他小程序跳转等方式进行的,这个有待测试。
分包预下载
在进入小程序某个页面时,由框架自动预下载可能需要的分包,提升进入后续分包页面时的启动速度。对于独立分包,也可以预下载主包。
预下载分包行为在进入某个页面时触发,通过在 app.json 增加 preloadRule 配置来控制。preloadRule 的成员为键值对,键是页面路径,值是进入此页面时的预下载配置。值的配置有2项:
字段 |
类型 |
必填 |
默认值 |
说明 |
packages |
String Array |
是 |
无 |
进入页面后预下载分包的root或name。_APP_表示主包 |
network |
String |
否 |
wifi |
在指定的网络下进行预下载,可选值为:all 不限网络/wifi 仅限wifi下 |
例:
{
"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__"] }
}
}
需要注意的是,同一个分包中的页面享有共同的预下载大小限额 2M,限额会在工具中打包时校验。