做小程序做到一定程度,基本都会碰到这个问题:代码加着加着,编译的时候突然报错了——主包超过 2MB。这时候就得拆分,把不常用的页面放到"分包"里。这篇文章把分包相关的知识点整理了一遍,包括限制是多少、JSON 怎么写、独立分包是什么、预下载怎么配。

微信小程序分包有哪些限制

微信对包的大小有几条硬性规定:

大小上限

主包:2MB

单个分包:2MB

所有包加起来(普通分包):20MB

所有包加起来(独立分包):16MB

注意这个 2MB 是指编译后的代码体积,不是你项目文件夹的大小。图片这些资源一般不算在主包体积内(除非你把 base64 图片塞进代码里了),所以真正吃掉主包空间的主要是 JS/WXML/WXSS/JSON 文件。

app.json 里怎么写

分包配置的核心字段叫 subPackages(注意大小写,S 和 P 都是大写的)。下面是一个最简单的例子:


// app.json
{
  "pages": ["pages/index/index"],
  "subPackages": [
    {
      "root": "packageA",
      "pages": [
        "pages/detail/detail",
        "pages/list/list"
      ]
    }
  ]
}
        

root 是分包的目录名,pages 是这个分包里的页面路径数组。pages 数组里的每一项都必须是相对于 root 的相对路径。

另外要注意:subPackages 里的页面不能和主包 pages 里的重复,也不能和其他分包里的页面重复。重复了微信开发者工具会报错。

普通分包 vs 独立分包

两种分包的区别其实就一句话:独立分包能不能单独跑

  • 普通分包:默认类型。依赖主包——用户必须先加载完主包,才能访问分包里的页面。但反过来,主包也可以访问分包的资源(前提是那个分包已经加载过了)。
  • 独立分包:在分包配置里加上 "independent": true。这种分包不依赖主包,可以独立运行。典型场景是活动推广页、临时运营页——用户可能从分享链接直接进来,没加载过主包。
独立分包的限制

独立分包虽然能独立运行,但它无法访问主包的公共资源(比如 app.wxss 里定义的全局样式、app.js 里定义的全局数据)。所以如果你的页面依赖这些东西,就不能做成独立分包。

预下载 preloadRule

默认情况下,分包是在用户进入对应页面时才下载的。如果网络慢,用户会看到一个白屏或加载动画。预下载就是让小程序在用户空闲时提前把分包下载下来:


// 用户进入首页时,后台静默下载 packageA
{
  "preloadRule": {
    "pages/index/index": {
      "network": "wifi",
      "packages": ["packageA"]
    }
  }
}
        

network 字段可以指定只在 WiFi 下预下载,省流量。packages 填要预下载的分包 root 名称。可以同时指定多个分包。

分包配置容易踩什么坑

  • tabBar 页面不能放在分包里——tabBar 页面必须在主包的 pages 数组中声明,这是硬性规定。
  • 分包之间不能互相引用——packageA 不能 import packageB 的 JS,如果需要共享逻辑,要么放主包,要么抽成 npm 包。
  • subPackagesroot 路径不能以 "/" 开头,也不能包含 "../",只能是简单的目录名。

分包配置工具有什么用

分包少的时候手写 JSON 没问题,分包一多(比如 5 个以上),手写就容易漏掉某个页面或者写错路径。速工具 的分包配置工具做的事情比较简单:可视化添加分包和页面,自动拼出 JSON 配置,你复制粘贴到项目里就行。不会帮你算实际体积——那得看编译结果,工具这边没法拿到。

常见问题

分包大小限制是多少?

整个小程序所有分包大小不能超过 20MB,单个分包不能超过 2MB(独立分包也是 2MB)。主包不能超过 2MB。如果超限,需要拆分资源到 CDN 或精简代码。图片资源建议上传到云存储用 URL 引用。

主包能引用分包的代码吗?

不能。主包不能 require 分包内的 JS 模块,也不能引用分包内的组件。但分包可以引用主包的代码。独立分包更严格——连主包的代码也不能引用,完全独立运行。

分包预下载失败会怎样?

预下载失败不会影响小程序正常运行,只是用户进入分包页面时需要重新下载。可以在 onDidLoad 回调中监听预下载结果,失败时提示用户。预下载会在用户网络空闲时进行,不会阻塞主包加载。