真香 - Webpack5 新特性之增量編譯
關(guān)注并將「趣談前端」設(shè)為星標
每早08:30按時推送技術(shù)干貨/優(yōu)秀開源/技術(shù)思維
webpack作為最使用最廣泛的前端打包工具,已經(jīng)成為前端工程化基礎(chǔ)設(shè)施的一部分。
webpack5正式發(fā)布于2020年10月10號,距離上一個大版本W(wǎng)ebpack4更新已經(jīng)是2年前年了,每個大版本的升級都會有相當多的改變和提升,今天咱們就來看看增量編輯和長期緩存。
增量編譯(官方稱作:優(yōu)化持久化緩存)
Webpack5之前在構(gòu)建時,會以配置的 entry 為入口,遞歸解析模塊依賴,構(gòu)建出一個依賴圖(graph),該依賴圖記錄代碼中各個 module 之間的關(guān)系。
ps: graph 是什么?圖是一種數(shù)據(jù)結(jié)構(gòu),類似下面這樣

每當有文件內(nèi)容更新的時候,會重新遞歸生成依賴圖,如果簡單粗暴地重建依賴圖再編譯,會有很大的性能開銷。在webpack5中,利用緩存實現(xiàn)增量編譯,從而提升構(gòu)建性能。每當代碼變化、模塊之間依賴關(guān)系改變導(dǎo)致依賴圖改變時, Webpack 會讀取記錄做增量編譯。
緩存(內(nèi)存 / 磁盤兩種形式)中的主要內(nèi)容是 module objects,在編譯的時候會將依賴圖以二進制或者 json 文件存儲在硬盤上。
之前持久緩存的方式
使用 cache-loader 可以將編譯結(jié)果寫入硬盤緩存,Webpack 再次構(gòu)建時如果文件沒有發(fā)生變化則會直接拉取緩存。 還有一部分 loader 自帶緩存配置,比如 babel-loader,可以配置參數(shù) cacheDirectory 使用緩存,將每次的編譯結(jié)果寫進磁盤(默認在 node_modules/.cache/babel-loader 目錄) terser-webpack-plugin 開啟緩存
webpack5持久緩存方式
v5 中緩存默認是 memory,你可以修改設(shè)置寫入硬盤:
module.export={
cache{
type:'filesystem', // 'memory' | 'filesystem'
cacheDirectory: 'node_modules/.cache/webpack', // 默認將緩存存儲在 node_modules/.cache/webpack
// 緩存依賴,當緩存依賴修改時,緩存失效
buildDependencies:{
// 將你的配置添加依賴,更改配置時,使得緩存失效
config: [__filename]
}
}
}
增量編譯體驗
下面來嘗試下這個功能,并同時和webpack4做下對比

為了能夠看出對比效果,搞了一堆模塊,不過代碼量都很少。
配置環(huán)境 - webpack4 安裝
下面使用yarn 安裝,本人習(xí)慣用yarn,因為速度夠快
// webpack4
yarn add webpack@4 webpack-cli@3 babel-loader @babel/core @babel/preset-env -D
const path=require('path');
module.exports={
mode:"development",
entry:{
index:'./src/pages/home/index.js' //入口文件
},
output:{
filename:'[name].js',
path:path.resolve(__dirname,'./dist') //指定生成的文件目錄
},
// 模塊
module:{
rules:[
{
test:/\.js$/,
exclude:/node_modules/,
use:[
{
loader:'babel-loader',
options:{
presets:[
'@babel/preset-env',
]
},
}
]
},
]
},
}
配置環(huán)境 - webpack5 安裝
// webpack5
yarn add webpack webpack-cli babel-loader @babel/core @babel/preset-env -D
const path=require('path'); 、
module.exports={
mode:"development", 、
entry:{
index:'./src/pages/home/index.js' 、
},
output:{
filename:'[name].js',、
path:path.resolve(__dirname,'./dist')、
},
cache: {
type: 'filesystem',//使用文件緩存
// cacheDirectory 默認路徑是 node_modules/.cache/webpack
cacheDirectory: path.resolve(__dirname, './temp_cache') //本地目錄
},
// 模塊
module:{
rules:[
{
test:/\.js$/,
exclude:/node_modules/,
use:[
{
loader:'babel-loader',
options:{
presets:[
'@babel/preset-env',
]
},
}
]
},
]
},
}
配置啟動命令
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "webpack --config webpack.config.js"
},
構(gòu)建結(jié)果對比
//執(zhí)行
yarn start
首次編譯 v5 done in 1.5s 左右
首次編譯 v4 done in 1.05s左
后續(xù)無修改編譯:v5 done in 0.6s 左右
后續(xù)無修改編譯:v4 done in 0.9s 左右
修改后編譯:v5 done in 1.5s 左右
修改后編譯:v4 done in 1.5s 左右
但v5里多了一個時間 webpack compiled successfully time,這個在v4里默認沒有顯示
V5 首次編譯 webpack compiled successfully in 723 ms
V5 無修改編譯 webpack compiled successfully in 100 ms
V5 修改后編譯 webpack compiled successfully in 417 ms
但我們應(yīng)該以 done in time 作為對比
構(gòu)建產(chǎn)物和日志
v5 緩存文件

v5首次編譯

v5 無修改2次編譯
直接讀取緩存

v5修改后編譯
增量編譯,只編譯修改的模塊

v4 首次編譯

v4 無修改2次編譯
全量編譯

v4 修改后編譯
全量編譯

總結(jié)
模塊較少,代碼量少時,增量編輯的優(yōu)勢并不明顯,甚至首次編譯的速度還會低于v4的速度,因為v5需要處理緩存。
增量編譯中:v5只編譯了修改的模塊,而v4每次編譯都是所有模塊重新編譯,全量執(zhí)行。
代碼量較少,性能提升不明顯,相信在復(fù)雜龐大的項目中會有更好的效果,因為增量編譯無疑會更節(jié)省cpu和內(nèi)存的使用率,后面試著把老項目升級下,看看最終的一個打包速度能提升多少。
今日一提就到這里,希望對你點幫助。
Webpack V5還有非常多的特性,比如長期緩存、更智能的tree shaking、模塊聯(lián)邦 等,一起來探索吧。
?? 看完三件事
如果你覺得這篇內(nèi)容對你挺有啟發(fā),我想邀請你幫我三個小忙:
點個【在看】,或者分享轉(zhuǎn)發(fā),讓更多的人也能看到這篇內(nèi)容
關(guān)注公眾號【趣談前端】,定期分享 工程化 / 可視化 / 低代碼 / 優(yōu)秀開源。

Dooring可視化搭建平臺數(shù)據(jù)源設(shè)計剖析
基于Koa + React + TS從零開發(fā)全棧文檔編輯器(進階實戰(zhàn))
點個在看你最好看

