Skip to content

工程化

第一章:npm 支持

一、构建 npm

目前小程序已经支持使用 npm 安装第三方包,但是这些 npm 包在小程序中不能够直接使用,必须得使用小程序开发者工具进行构建后才可以使用。

为什么得使用小程序开发者工具需要构建呢?

因为 node_modules 目录下的包,不会参与小程序项目的编译、上传和打包。因此,在小程序项目中要想使用 npm 包,必须走一遍构建 npm 的过程。

在构建成功以后,默认会在小程序项目根目录,也就是 node_modules 同级目录下生成 miniprogram_npm 目录,里面存放这构建打包后的 npm 包,也就是小程序运行过程中真正使用的包。

微信开发者工具如何构建?

我们以使用 Vant Weapp 小程序 UI 组件库为例,来说明小程序如何安装和构建 npm,构建 npm 的步骤如下:

① 初始化 package.json

② 通过 npm 安装项目依赖

③ 通过微信开发者工具构建 npm

📌 注意事项

① 小程序运行在微信内部,因为运行环境的特殊性,这就导致并不是所有的包都能够在小程序使用。

② 我们在小程序中提到的包指专为小程序定制的 npm 包,简称小程序 npm 包,在使用包前需要先确定该包是否支持小程序。

③ 开发者如果要发布小程序包,需要参考官方规范:https://developers.weixin.qq.com/miniprogram/dev/devtools/npm.html#发布-npm-包

④ 一般都会将 app.json 中的 "style": "v2" 去除。小程序的新版基础组件强行加上了许多样式,难以覆盖,不关闭将造成部分组件样式混乱。

二、自定义构建 npm

在实际的开发中,随着项目的功能越来越多、项目越来越复杂,文件目录也变的很繁琐,为了方便进行项目的开发,开发人员通常会对目录结构进行调整优化。例如:将小程序源码放到 miniprogram 目录下。

但是在调整目录以后,我们按照上一小节 Vant Weapp 的构建流程进行构建,发现没有构建成功,并且弹出构建失败的弹框。

[错误提示翻译意思是] :没有找到可以构建的 npm 包。

[解决方式]:

① 请确认需要参与构建的 npm 都在 miniprogramRoot 目录内。

② 配置 project.config.jsonpackNpmManuallypackNpmRelationList 进行构建。

产生这个错误的原因是因为小程序的构建方式有两种

  • 默认构建 npm

    默认情况下,不使用任何模版,miniprogramRoot 是小程序项目根目录,在 miniprogramRoot 内正确配置了 package.json 并执行 npm install 之后,在项目的根目录下就有 node_modules 文件夹,然后对 node_modules 中的 npm 进行构建,其构建 npm 的结果是,为 package.json 对应的 node_modules 构建一份 miniprogram_npm,并放置在对应 package.json 所在目录的子目录中。

  • 自定义构建 npm

    默认的构建 npm 方式不一样,自定义构建 npm 的方式为了更好的优化目录结构,更好的管理项目中的代码。

    需要开发者在 project.config.json 中指定 node_modules 的位置 和 目标 miniprogram_npm 的位置。

解决方案

project.config.json 中详细的配置流程和步骤如下:

① 新增 miniprogramRoot 字段,指定调整后了的小程序开发目录。

② 新增 setting.packNpmManually设置为 true,开启指定 node_modules 的位置以及构建成功后文件的位置。

③ 新增 setting.packNpmRelationList 项,指定 packageJsonPathminiprogramNpmDistDir 的位置。

  • packageJsonPath 表示 node_modules 源对应的 package.json
  • miniprogramNpmDistDir 表示 node_modules 的构建结果目标位置。

第二章:分包加载

一、什么是分包加载

小程序的代码通常是由许多页面、组件以及资源等组成,随着小程序功能的增加,代码量也会逐渐增加,体积过大就会导致用户打开速度变慢,影响用户的使用体验。

分包加载是一种小程序优化技术。将小程序不同功能的代码,分别打包成不同的子包,在构建时打包成不同的分包,用户在使用时按需进行加载,在构建小程序分包项目时,构建会输出一个或多个分包。每个使用分包小程序必定含有一个主包。每个分包可以包含多个页面、组件、样式和逻辑等。当小程序需要使用某个分包时,才会加载该分包中的代码。

**主包:**包含默认启动页面 / TabBar 页面,以及所有分包都需用到公共资源的包。

**分包:**根据开发者的配置进行划分出来的子包。

二、小程序分包后如何加载

在小程序启动时,默认会下载主包并启动主包内页面,在用户访问分包内某个页面时,微信客户端才会把对应分包下载下来,下载完成后再进行展示。

目前小程序分包大小有以下限制:

  • 整个小程序所有分包大小不超过 20MB。
  • 单个分包 / 主包大小不能超过 2MB。

三、分包的基本使用

在进行分包加载之前,需要对小程序的业务逻辑进行分析,将代码划分成多个模块。每个模块应该有一个明确的功能,并与其他模块之间有明确的依赖关系。

开发者在小程序的配置文件 app.json 中,通过 subPackages 或者 subpackages 字段声明项目分包结构。

每个分包需要指定 root 字段、name 字段和 pages 字段。

  • root 字段指定了分包的根目录,该目录下的所有文件都会被打包成一个独立的包。
  • name 字段为分包的名称,用于在代码中引用该分包。
  • pages 字段指定了该分包中包含的页面,可以使用通配符 * 匹配多个页面。
json
{
  "subPackages": [
    {
      "root": "modules/goodModule",
      "name": "goodModule",
      "pages": [
        "pages/list/list",
        "pages/detail/detail"
      ]
    },
    {
      "root": "modules/marketModule",
      "name": "marketModule",
      "pages": [
        "pages/market/market"
      ]
    }
  ]
}

四、打包和引用原则 (注意事项)

打包原则

  1. tabBar 页面必须在主包内。

  2. 最外层的 pages 字段,属于主包的包含的页面。

  3. 按 subpackages 配置路径进行打包,配置路径外的目录将被打包到主包中。

  4. 分包之间不能相互嵌套。subpackage 的根目录不能是另外一个 subpackage 内的子目录。

引用原则

  1. 主包不可以引用分包的资源,但分包可以使用主包的公共资源。

  2. 分包与分包之间资源无法相互引用, 分包异步化时不受此条限制。

五、独立分包的配置

1. 什么是独立分包

独立分包是小程序中一种特殊类型的分包,可以独立于主包和其他分包运行。

从独立分包中页面进入小程序时,不需要下载主包。只有当用户进入普通分包或主包内页面时,主包才会被下载!

开发者可以将功能相对独立的页面配置到独立分包中,因为独立分包不依赖主包即可运行,可以很大程度上提升分包页面的启动速度。

如果是独立分包,不需要下载主包,直接就能够访问,独立分包是自己独立运行的。

而如果是其他分包,需要先下载主包,通过路径访问,才能加载对应路径的分包。

📌 注意事项

① 独立分包中不能依赖主包和其他分包中的资源。

② 主包中的 app.wxss 对独立分包无效。

③ App 只能在主包内定义,独立分包中不能定义 App,会造成无法预期的行为。

2. 如何配置独立分包

开发者在 app.json 中找到需要配置为独立分包的 subpackages 字段。

在该字段配置项中定义 independent 字段声明对应分包为独立分包。

json
{
  "subPackages": [
    {
      "root": "modules/goodModule",
      "name": "goodModule",
      "pages": [
        "pages/list/list",
        "pages/detail/detail"
      ]
    },
    {
      "root": "modules/marketModule",
      "name": "marketModule",
      "pages": [
        "pages/market/market"
      ],
        "independent": true
    }
  ]
}

六、分包预下载

分包预下载是指访问小程序某个页面时,预先下载分包中的代码和资源,以提高用户的使用体验。当用户需要访问分包中的页面时,已经预先下载的代码和资源可以直接使用,通过分包预下载加快了页面的加载速度和显示速度。

小程序的分包预下载需要在 app.json 中通过 preloadRule 字段设置预下载规则。preloadRule 是一个对象,对象的 key 表示访问哪个路径时进行预加载,value 是进入此页面的预下载配置,具有两个配置项:

字段类型必填默认值说明
packagesStringArray预下载的分包名称,进入页面后预下载分包的 rootname
__APP__ 表示主包。
networkStringwifi在指定网络下预下载,
可选值为: all: 不限网络 wifi: 仅wifi下预下载

代码:

json
{
  "subPackages": [
    {
      "root": "modules/goodModule",
      "name": "goodModule",
      "pages": [
        "pages/list/list",
        "pages/detail/detail"
      ]
    },
    {
      "root": "modules/marketModule",
      "name": "marketModule",
      "pages": [
        "pages/market/market"
      ],
      "independent": true
    }
  ],
  "preloadRule": {
    "pages/index/index": {
      "network": "all",
      "packages": ["modules/goodModule"]
    },
    "modules/marketModule/pages/market/market": {
      "network": "all",
      "packages": ["__APP__"]
    }
  }
}

Released under the MIT License.