寻觅 webpack - 27 - 真实世界的 webpack - 建立 webpack 生产环境 - 追踪建置

本系列已集结成书从 0 到 Webpack:学习 Modern Web 专案的建置方式,这是一本完整介绍 Webpack 的专书,如有学习 Webpack 相关的问题可以参考此书。

本文讲述如何使用分析工具解析 bundle 内模组的组合。

本文的范例程序放在 peterhpchen/webpack-quest 中,每个程序码区块的第一行都会标注档案的位置,请搭配文章作参考。

开发者在完成 webpack 的配置并且可以执行後,通常就不会再去注意 webpack 每此打包出来的 bundle 了,但其实比较好的做法是持续的追踪 webpack 所产生出来的 bundle ,随着应用程序开发时程,整体体积会跟着提高,这时就需要跟着变化去改变 webpack 配置,以确保应用程序的效能处於高档的状态。

使用 performance 配置提示 bundle 状态

webpack 提供 performance 配置让使用者可以设定输出状态的限制,如果输出的 bundle 超过 performance 所设定的临界值,则会输出资讯供开发者调整 bundle 的组成。

下面的例子配置 performance

// ./demos/performance/webpack.config.js
module.exports = {
  mode: "none",
  performance: {
    hints: "warning",
    maxEntrypointSize: 100,
    maxAssetSize: 100,
  },
};

performance 是个物件型态的配置,属性说明如下:

  • hints:设定输出的强弱程度
    • false: 不显示资讯
    • 'warning': 以 warning 程度显示资讯
    • 'error': 以 error 程度显示资讯
  • maxEntrypointSize: 入口点型态的 bundle 最大体积限制值,单位为 Byte
  • maxAssetSize: 所有输出 bundle 的最大体积限制值,单位为 Byte

使用 ./demos/performance 建置资讯如下图:

https://ithelp.ithome.com.tw/upload/images/20201012/20107789qo14kUJI00.png

从这里可以看出 maxEntrypointSizemaxAssetSize 的差别, maxEntrypointSize 所设定的对象仅限於 entry bundle main.js ,而 maxAssetSize 包含了其他的 bundle (例如非同步的 bundle)。

performance 的预设值

performance 在各模式下的预设值如下:

模式 hints maxEntrypointSize maxAssetSize
development false 250000 250000
production 'warning' 250000 250000
none false 250000 250000

输出资讯

webpack 提供了各种的输出供使用者参考,以调整最佳的建置方式, CLI 工具中可以使用各种参数做不同的输出:

--profile: 显示各模组的建置时间
--progress: 显示各个编译过程资讯及花费时间

https://ithelp.ithome.com.tw/upload/images/20201012/20107789YHwvfifgTh.png

如此一来可以掌握建置时花费时间的模组或是过程,从而针对问题做解决。

除了上述的两个以外,还有 --json 参数,它会以 .json 格式输出建置的结果细节,由於资讯较多,因此需要避免直接在 terminal 中开启,改为写入档案中。

webpack --json > stats.json

上面的例子将建置的资讯 stats 写入 states.json 中,我们看一下它的内容:

// ./demos/cli-args-json/stats.json
{
  "errors": [],
  "warnings": [],
  "version": "4.44.2",
  "hash": "dc8fccd110b852a7e550",
  "time": 59,
  "builtAt": 1602384822101,
  "publicPath": "",
  "outputPath": "/Users/peterchen/Documents/webpack-quest/posts/27-production-analyze/demos/cli-args-json/dist",
  "assets": [...], // 输出的资源资讯
  "entrypoints": {...}, // 入口模组资讯
  "chunks": [...], // webpack 内组成的 chunks 资讯
  "modules": [...], // 各模组资讯
  "logging": {...},
  "children": [] // 多组建置时上述内容会在 children 阵列中
}

stats 资讯拥有完整的建置资讯,在使用 Node.js API 操作 webpack 一文中所提到的 stats.toJson() 与此资讯相同,不管是 CLI 的输出资讯还是 Node.js API 的 stats 都是仰赖这些资讯输出有用的讯息。

监控 bundle 的体积

bundle 的体积虽然在 performance 设定的帮忙下可以提出警示,但依然只是在有超过临界点时才会输出资讯 ,并不能看到整个 bundle 後的全貌,这时我们可以使用 webpack-dashboard 来观察 bundle 的情况。

首先安装 webpack-dashboard:

npm install webpack-dashboard -D

接着将 WebpackDashboardPlugin 加入配置:

// ./demos/dashboard-demo/webpack.config.js
const WebpackDashboardPlugin = require("webpack-dashboard/plugin");

module.exports = {
  mode: "none",
  entry: {
    main: ["./src/index.js", "./src/index2.js"],
    sub: "./src/sub.js",
  },
  plugins: [new WebpackDashboardPlugin()],
};

另外要修改建置的指令,改以 webpack-dashboard 触发建置指令:

{
    ...
  "scripts": {
    "build": "webpack-dashboard -- webpack"
  },
  ...
}

建置结果如下:

webpack-dashboard-demo

我们可以很清楚的看到各个模组的组成,这样一来大大增加了我们对 bundle 的理解及给予我们更多的资讯。

警示 bundle 过大

performance 所警示的对象细粒度只有到 assets ,有时候我们会需要在监控不同的档案时使用的限制也要有所不同,这是 performance 做不到的。接下来介绍一个 bundle-size 的工具,他可以以模组为对象做警示。

首先来安装:

npm install bundlesize -D

并且加入 bundlesize 指令:

{
    ...
  "scripts": {
      ...
    "check": "bundlesize"
  },
  ...
}

bundlesize 是个通用工具,并不绑定 webpack ,因此我们要给予 bundlesize 输出目录的资讯,让它可以藉由此资讯找寻所需的 bundle :

// ./demos/bundlesize-demo/bundlesize.config.json
{
  "files": [
    {
      "path": "./dist/main.js",
      "maxSize": "1 KB"
    }
  ]
}

这里设定要检查 ./dist/main.js 的大小是否超过 1 KB ,执行 bundlesize 後,可以看到错误提示:

https://ithelp.ithome.com.tw/upload/images/20201012/20107789HNhe4CP5G8.png

总结

webpack 可以自己利用 performance 的能力警示建置後的 bundle 是否有超过限制,也可以使用 bundlesize 做更精确对象的判断。

而 CLI 另外还提供 --profile--progress 可以让使用者知道建置时的花费如何,也可以利用 --json 输出完整的 stats

另外仰赖 webpack-dashboard 可以清楚地了解各个模组的资讯,以此让使用者可以观察并作相关的优化。

参考资料


<<:  iris的routing

>>:  【30天Lua重拾笔记28】进阶议题: Meta Programming

Neo4j 的 GraphQL 计画:GRANDstack

上一篇文章开启了 GraphQL 的话题,介绍 Neo4j GraphQL plugin 的使用,让...

[FHIR 从入门到放弃] Day 02-FHIR 基本概念

因为工作关系,忙到没空写文,拖稿拖了好久...... FHIR 是什麽,能吃吗? 为什麽会有 FHI...

[Day 4 ] 步入学程序的第一关

前言: 虽然常接触电脑文书操作,但都没有使用指令经验,一开始甚至不知道终端机该从何开启,怎麽美化介面...

第十七天:TeamCity 通知机制

自从有了 TeamCity 後,很多原本需要人工操作的任务都可以交给 CI 主机做。因为它会在每一次...

卡夫卡的藏书阁【Book5】- Kafka 安装与基本设定

“I am a cage, in search of a bird.” ― Franz Kafka...