分享幾個(gè) Webpack 實(shí)用分析工具
全文 1500 字,閱讀時(shí)長(zhǎng)約 15 分鐘。如果覺(jué)得文章有用,歡迎點(diǎn)贊關(guān)注,但寫(xiě)作實(shí)屬不易,未經(jīng)作者同意,禁止任何形式轉(zhuǎn)載!!!?
設(shè)想一個(gè)場(chǎng)景,假如需要提升 webpack 編譯速度,或者優(yōu)化編譯產(chǎn)物大小,應(yīng)該從何下手?別急,在采用具體手段前,可以先花點(diǎn)時(shí)間了解當(dāng)前的編譯執(zhí)行情況,確定性能瓶頸,有的放矢!今天就給大家分享一些 webpack 構(gòu)建過(guò)程的分析診斷方法和工具,基于這些工具,你可以:
了解編譯產(chǎn)物由那些模塊資源組成 了解模塊之間的依賴關(guān)系 了解不同模塊的編譯構(gòu)建速度 了解模塊在最終產(chǎn)物的資源占比 等等
收集統(tǒng)計(jì)信息
Webpack 運(yùn)行過(guò)程會(huì)收集各種統(tǒng)計(jì)信息,只需要在啟動(dòng)時(shí)附加 --json 參數(shù)即可獲得:
npx webpack --json > stats.json
上述命令運(yùn)行后,會(huì)在文件夾下輸出 stats.json 文件,文件內(nèi)容主要包含:
{
"hash": "2c0b66247db00e494ab8",
"version": "5.36.1",
"time": 81,
"builtAt": 1620401092814,
"publicPath": "",
"outputPath": "/Users/tecvan/learn-webpack/hello-world/dist",
"assetsByChunkName": { "main": ["index.js"] },
"assets": [
// ...
],
"chunks": [
// ...
],
"modules": [
// ...
],
"entrypoints": {
// ...
},
"namedChunkGroups": {
// ...
},
"errors": [
// ...
],
"errorsCount": 0,
"warnings": [
// ...
],
"warningsCount": 0,
"children": [
// ...
]
}
通常,分析構(gòu)建性能時(shí)主要關(guān)注如下屬性:
「assets」 :編譯最終輸出的產(chǎn)物列表 「chunks」 :構(gòu)建過(guò)程生成的 chunks 列表,數(shù)組內(nèi)容包含 chunk 名稱、大小、依賴關(guān)系圖 「modules」 :本次運(yùn)行觸達(dá)的所有模塊,數(shù)組內(nèi)容包含模塊的大小、所屬chunk、分析耗時(shí)、構(gòu)建原因等 「entrypoints」 :entry 列表,包括動(dòng)態(tài)引入所生產(chǎn)的 entry 項(xiàng)也會(huì)包含在這里面 「namedChunkGroups」 :chunks 的命名版本,內(nèi)容相比于 chunks 會(huì)更精簡(jiǎn) 「errors」 :構(gòu)建過(guò)程發(fā)生的所有錯(cuò)誤信息 「warnings」 :構(gòu)建過(guò)程發(fā)生的所有警告信息
基于這些屬性,我們可以分析出模塊的依賴關(guān)系、模塊占比、編譯耗時(shí)等信息,不過(guò)這里大致了解原理就行了,社區(qū)已經(jīng)為我們提供了非常多事半功倍的分析工具。
可視化分析工具
Webpack Analysis
Webpack Analysis 是 webpack 官方提供的可視化分析工具,相比于其它工具,它提供的視圖更全,功能更強(qiáng)大,使用上只需要將上一節(jié) webpack --json > stats.json 命令生成的 stats.json 文件拖入頁(yè)面,就可以獲得一系列分析視圖:

點(diǎn)擊 「modules/chunks/assets」 按鈕,頁(yè)面會(huì)渲染出對(duì)應(yīng)依賴關(guān)系圖,例如點(diǎn)擊 「modules」:

除 「modules/chunks/assets」 外,右上方菜單欄 「Hints」 還可以查看構(gòu)建過(guò)程各階段、各模塊的處理耗時(shí),可以用于分析構(gòu)建的性能瓶頸:

?不過(guò),實(shí)測(cè)發(fā)現(xiàn) 「Hints」 還不支持 webpack 5 版本的產(chǎn)出,等待官方更新吧。
?
Webpack Analysis 提供了非常齊全的分析視角,信息幾乎不失真,但這也意味著上手難度更高,信息噪音也更多,所以社區(qū)還提供了一個(gè)簡(jiǎn)化版 webpack-deps-tree,用法相似但用法更簡(jiǎn)單、信息更清晰,讀者可以根據(jù)實(shí)際場(chǎng)景對(duì)比交叉使用。
Webpack Visualizer
Webpack Visualizer 是一個(gè)在線分析工具,同樣只需要將 stats.json 文件拖入頁(yè)面,就可以從文件夾到模塊逐層看到 bundle 的組成:

?除了在線版本外,Webpack Visualizer 還提供了插件版本的 webpack-visualizer-plugin 工具,但是這個(gè)插件年久失修,只兼容 webpack 1.x ,所以現(xiàn)在幾乎沒(méi)有使用價(jià)值了。
?
此外,在線工具 Webpack Chart 也提供了類似的功能,功能重合度很高,這里就不展開(kāi)講了。
Webpack Bundle Analyzer
webpack-bundle-analyzer 是一個(gè) webpack 插件,只需要簡(jiǎn)單的配置就可以在 webpack 運(yùn)行結(jié)束后獲得 treemap 形態(tài)的模塊分布統(tǒng)計(jì)圖,用戶可以仔細(xì)對(duì)比 treemap 內(nèi)容推斷是否包含重復(fù)模塊、不必要的模塊等場(chǎng)景,例如:
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer")
.BundleAnalyzerPlugin;
module.exports = {
...
plugins: [new BundleAnalyzerPlugin()],
};
編譯結(jié)束后,默認(rèn)自動(dòng)打開(kāi)本地視圖頁(yè)面:

此外,webpack-bundle-size-analyzer 也提供了類似,但是基于命令行視圖的分析功能,可以基于 webpack-bundle-size-analyzer 做一些自動(dòng)分析、自動(dòng)預(yù)警功能。
Webpack Dashboard
webpack-dashboard 是一個(gè)命令行可視化工具,能夠在編譯過(guò)程中實(shí)時(shí)展示編譯進(jìn)度、模塊分布、產(chǎn)物信息等,與 webpack-bundle-size-analyzer 類似,它也只需要一些簡(jiǎn)單的改造就能運(yùn)行,首先需要注冊(cè)插件:
const DashboardPlugin = require("webpack-dashboard/plugin");
module.exports = {
// ...
plugins: [new DashboardPlugin()],
};
其次,修改 webpack 的啟動(dòng)方式,例如原來(lái)的啟動(dòng)命令可能是:
"scripts": {
"dev": "node index.js", # OR
"dev": "webpack-dev-server", # OR
"dev": "webpack",
}
需要修改為:
"scripts": {
"dev": "webpack-dashboard -- node index.js", # OR
"dev": "webpack-dashboard -- webpack-dev-server", # OR
"dev": "webpack-dashboard -- webpack",
}
之后,就可以在命令行看到一個(gè)漂亮的可視化界面:

UnusedWebpackPlugin
最后分享 UnusedWebpackPlugin 插件,它能夠根據(jù) webpack 統(tǒng)計(jì)信息,反向查找出工程項(xiàng)目里那些文件沒(méi)有被用到,我日常在各種項(xiàng)目重構(gòu)工作中都會(huì)用到,非常實(shí)用。用法也比較簡(jiǎn)單:
const UnusedWebpackPlugin = require("unused-webpack-plugin");
module.exports = {
// ...
plugins: [
new UnusedWebpackPlugin({
directories: [path.join(__dirname, "src")],
root: path.join(__dirname, "../"),
}),
],
};
示例中,directories 用于指定需要分析的文件目錄;root 用于指定根路徑,與輸出有關(guān)。配置插件后,webpack 每次運(yùn)行完畢都會(huì)輸出 directories 目錄中,有那些文件沒(méi)有被用到:

總結(jié)
工欲善其事,必先利其器!上面分享的工具都在解決相似的問(wèn)題 —— 構(gòu)建分析,只是具體的側(cè)重點(diǎn)、用法、交互形態(tài)略有不同,讀者可以結(jié)合實(shí)際場(chǎng)景,擇優(yōu)選用。
