分包能直接解决主包超2MB问题,但必须将subPackages正确配置在pages.json根级(与pages、tabBar平级),root路径需相对src且不以/或..开头,跳转url须带完整路径,H5/App平台忽略该配置。

分包能直接解决主包超 2MB 的问题,但配错位置、路径或平台开关,就等于没配。
subPackages 必须写在 pages.json 根级,不是 manifest.json 也不是 subNVue
很多人改完 pages.json 没效果,第一反应是“uni-app 不支持分包”,其实是写错了地方。它必须和 pages、tabBar 平级,不能嵌套进任何其他字段里:
-
subPackages是数组,每一项含root(相对src的子包路径)和pages(该包内页面路径数组) -
root不能以/或..开头,比如"root": "subPackages/user"✅,"root": "/subPackages/user"❌ - 别和
subNVue混,后者是原生子窗体,和分包无关;也别往manifest.json里塞,那里不认这个字段 - H5 和 App 平台完全忽略
subPackages,只对小程序生效
跳转分包页面时 url 必须带完整路径,uni.navigateTo 不会自动补前缀
写错路径最常见后果是白屏,控制台可能没报错,但 Network 面板能看到 404 请求:
- 正确写法:
uni.navigateTo({ url: '/subPackages/user/pages/profile/profile' })—— 开头有/,且层级与root+pages.path拼起来完全一致 - 错误写法:
uni.navigateTo({ url: 'profile' })、uni.navigateTo({ url: 'pages/profile/profile' })、uni.navigateTo({ url: 'subPackages/user/profile' }) -
uni.switchTab只能跳主包里的 tab 页面,子包页面不能配置在tabBar.list中 - 动态拼接
url时务必.trim(),空格或换行会导致路径失效
preloadRule 预加载要三处对齐:manifest 开关 + pages.json 路径 + packages 字符串
预加载不是“写了就生效”,漏掉任意一环都会静默失败:
- 必须在
manifest.json的mp-weixin节点下开启:"optimization": {"subPackages": true} -
preloadRule的 key(如"pages/index/index")必须和pages.json中主包页面的path完全一致,包括大小写和后缀 -
packages数组里的字符串,必须和某个subPackages项的root值**逐字相同**,比如"root": "subPackages/user",那就要写"packages": ["subPackages/user"],不能简写成"user" -
network别一上来就设"all",弱网下可能抢带宽拖慢首屏;先用"wifi"测试,确认日志里出现preloading或downloadSubNVue再调整
static 和 common 资源默认打进主包,分包目录下的 static 不自动归属分包
这是体积反复超限的隐藏元凶——你以为把图片放进 subPackages/user/static 就安全了,其实 uni-app 默认把所有 static 和 common 打进主包:
- 主包体积悄悄膨胀,分包失去意义
- 解决方案:分包专用资源必须放在分包目录内,且引用路径写成相对路径(如
../static/img/logo.png),同时确保主包页面没引用这些路径 - 大图、视频等资源建议直接上 CDN,别打包进任何包
- 检查是否误将 UI 库(如 uView)、地图 SDK 全局引入,它们会强制进入主包;改为按需导入或分包内局部引入
最容易被忽略的是 manifest.json 里那个 optimization.subPackages 开关,以及 subPackages 里 root 路径和实际文件系统的一致性——大小写、斜杠、层级,差一个字符,分包就形同虚设。











