學到了!Webpack5 新特性之增量編譯
webpack作為最使用最廣泛的前端打包工具,已經(jīng)成為前端工程化基礎設施的一部分。
webpack5正式發(fā)布于2020年10月10號,距離上一個大版本W(wǎng)ebpack4更新已經(jīng)是2年前年了,每個大版本的升級都會有相當多的改變和提升,今天咱們就來看看增量編輯和長期緩存。
增量編譯(官方稱作:優(yōu)化持久化緩存)
Webpack5之前在構建時,會以配置的 entry 為入口,遞歸解析模塊依賴,構建出一個依賴圖(graph),該依賴圖記錄代碼中各個 module 之間的關系。
ps: graph 是什么?圖是一種數(shù)據(jù)結構,類似下面這樣

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

為了能夠看出對比效果,搞了一堆模塊,不過代碼量都很少。
配置環(huán)境 - webpack4 安裝
下面使用yarn 安裝,本人習慣用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"
},
構建結果對比
//執(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
但我們應該以 done in time 作為對比
構建產(chǎn)物和日志
v5 緩存文件

v5首次編譯

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

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

v4 首次編譯

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

v4 修改后編譯
全量編譯

總結
模塊較少,代碼量少時,增量編輯的優(yōu)勢并不明顯,甚至首次編譯的速度還會低于v4的速度,因為v5需要處理緩存。
增量編譯中:v5只編譯了修改的模塊,而v4每次編譯都是所有模塊重新編譯,全量執(zhí)行。
代碼量較少,性能提升不明顯,相信在復雜龐大的項目中會有更好的效果,因為增量編譯無疑會更節(jié)省cpu和內(nèi)存的使用率,后面試著把老項目升級下,看看最終的一個打包速度能提升多少。
今日一提就到這里,希望對你點幫助。
Webpack V5還有非常多的特性,比如長期緩存、更智能的tree shaking、模塊聯(lián)邦 等,一起來探索吧。
最后
如果你覺得這篇內(nèi)容對你挺有啟發(fā),我想邀請你幫我三個小忙:
點個「在看」,讓更多的人也能看到這篇內(nèi)容(喜歡不點在看,都是耍流氓 -_-)
歡迎加我微信「qianyu443033099」拉你進技術群,長期交流學習...
關注公眾號「前端下午茶」,持續(xù)為你推送精選好文,也可以加我為好友,隨時聊騷。

