webpack文件系統(tǒng)緩存

Webpack4的緩存方案
在使用Webpack4以及之前的版本時,我們都會注意到這樣的現(xiàn)象:
代碼熱更新很快npm run start慢npm run build慢
這種現(xiàn)象的本質(zhì)是:Webpack4在運(yùn)行時是有緩存的,只不過緩存只存在于內(nèi)存中。所以,一旦Webpack的運(yùn)行程序被關(guān)閉,這些緩存就丟失了。這就導(dǎo)致我們npm run start/build的時候根本無緩存可用。
所以,解決問題的辦法就是把這些Webpack編譯過程中的產(chǎn)生的緩存持久化到本地磁盤、數(shù)據(jù)庫或者云端。這里面涉及到兩點(diǎn):要持久化什么,持久化到哪里。
Webpack本身就已經(jīng)有一套緩存方案,只是不夠完善,不支持持久化。站在現(xiàn)在的角度來看,我們應(yīng)該直接去完善Webpack核心代碼,補(bǔ)充上持久化緩存的功能,使用一套緩存方案解決所有問題,這是顯而易見的。
然而,當(dāng)時社區(qū)好像沒搞清楚“要持久化什么”這個問題, 他們沒有在Webpack核心代碼上發(fā)力,而是選擇了從外部解決。于是就出現(xiàn)了cache-loader、dll等技術(shù),雖然在一定程度上解決了問題,但卻引入了過多的復(fù)雜性。
Webpack5的緩存方案
實(shí)際上,“要持久化什么”這個問題從一開始就是顯而易見的:是Webpack運(yùn)行時存在于內(nèi)存中的那些緩存,不是loader的產(chǎn)物,更不是dll。因此,Webpack5提供了一套持久化抽象,將數(shù)據(jù)存放在文件系統(tǒng)中
Webpack5直接從內(nèi)部核心代碼的層面,統(tǒng)一了持久化緩存的方案,有效降低了緩存配置的復(fù)雜性。除此之外,由于所有被webpack處理的模塊都會被緩存,我們npm run start/build的二次編譯速度會遠(yuǎn)超cache-loader,同時dll也可以退出歷史舞臺了。
Webpack4時之所以要有dll,是因?yàn)閏ache-loader并不能覆蓋所有模塊,只能對個別被loader處理的模塊進(jìn)行緩存。而那些通用的庫是沒法被cache-loader處理的,所以只能通過dll的方式來預(yù)編譯。
實(shí)際上,Webpack5的內(nèi)置緩存方案無論從性能上還是安全性上都要好于cache-loader。
性能上:由于所以被webpack處理的模塊都會被緩存,緩存的覆蓋率要高的多。
安全上:由于cache-loader使用了基于mtime的緩存驗(yàn)證機(jī)制,導(dǎo)致在CI環(huán)境中緩存經(jīng)常會失效,但是Webpack5改用了基于文件內(nèi)容etag的緩存驗(yàn)證機(jī)制,解決了這個問題。
Webpack5的緩存使用
const path = require("path");const HtmlWebpackPlugin = require("html-webpack-plugin");module.exports = {mode: "development",entry: "./src/index.js",cache: {type: "filesystem", // 'memory' | 'filesystem'cacheDirectory: path.resolve(__dirname, "node_modules/.cache/webpack"), // 保存目錄},output: {filename: "bundle.js",path: path.resolve(__dirname, "dist"),},devtool: false,module: {rules: [{test: /\.js$/,use: [{loader: "babel-loader",options: {presets: ["@babel/preset-react"],},},],exclude: /node_modules/,},],},devServer: {},plugins: [new HtmlWebpackPlugin({template: "./public/index.html",}),],};
cache: true 與 cache: { type: 'memory' } 配置作用一致,表示緩存在內(nèi)存中。cache.type 設(shè)置為 'filesystem' 時,表示緩存在文件系統(tǒng)中。
