Webpack5 新特性業(yè)務(wù)落地實戰(zhàn)
本文作者:Wind、Skyler、ZRJ、ZJ
前言
Webpack5 在 2020 年 10 月 10 日正式發(fā)布,并且在過去的幾個月中快速演進(jìn)和迭代,截止 1 月 28 日,Webpack5 已經(jīng)更新了 18 個 minor 版本,帶來了許多十分吸引人的新特性。據(jù)官網(wǎng)介紹[1],Webpack5 整體的方向性變化有以下幾點:

通過持久化硬盤緩存能力來提升構(gòu)建性能 通過更好的算法來改進(jìn)長期緩存(降低產(chǎn)物資源的緩存失效率) 通過更好的 Tree Shaking 能力和代碼的生成邏輯來優(yōu)化產(chǎn)物的大小 改善 web 平臺的兼容性能力 清除了內(nèi)部結(jié)構(gòu)中,在 Webpack4 沒有重大更新而引入一些新特性時所遺留下來的一些奇怪的 state 通過引入一些重大的變更為未來的一些特性做準(zhǔn)備,使得能夠長期的穩(wěn)定在 Webpack5 版本上
最后的兩點介紹比較抽象,但整體可以看出,其實升級 Webpack5 對于開發(fā)者而言,能夠感知到的就是構(gòu)建時的效率和運行時的性能都有著明顯的提升,包括一些新特性可能給我們帶來的更舒適的“coding 姿勢”。
團(tuán)隊實踐
團(tuán)隊目前使用的是 Webpack4 來承接整套構(gòu)建體系,遷移時我們參考了 Webpack 官方提供的升級手冊[2],這里我們針對一些對我們的業(yè)務(wù)現(xiàn)階段有實際價值的點(新特性基本都有實際收益),集成到了團(tuán)隊的構(gòu)建流程中,通過實踐驗證并記錄了我們在基建落地的過程中遇到的一些問題和解決方法。
準(zhǔn)備工作
前期調(diào)研
首先,通過官方文檔給出的指引我們可以找出一些明確需要有改動的地方,其中就包括了如下幾個方面:
Webpack5 需要 Node 版本 ^10.13.0 的支持。本地使用的時候,需要將 Node 版本升級到 10.13.0 以上。對于使用了一些 CI 工具進(jìn)行產(chǎn)物構(gòu)建的時候,也需要同步升級對應(yīng)鏡像或者 CI 上配置的 Node 版本。 項目中的 html-webpack-plugin 需要升級的到支持 Webpack5 的版本[3] 項目中有使用到 workbox-webpack-plugin 需要升級到支持 Webpack5 的版本 DevServer 需要升級 webpack-dev-server 至 ^4(next) 版本,否則 HMR 會有異常。 Webpack5 移除了 Node.js Polyfill,將會導(dǎo)致一些包變得不可用(會在控制臺輸出 'XXX' is not defined),如果需要兼容 process 等 Nodejs Polyfill,則要安裝相關(guān)的 Polyfill:process,并在 Plugin 中顯式聲明注入
//?webpack.config.js
{
????...,
????plugins:?[
????????...,
????????new?webpack.ProvidePlugin({
??????????process:?'process/browser',
????????}),
????]
}
如果你在使用 Webpack5 的時候遇到一些 API 的棄用警告,可以果斷搜索 Google,一般都是讓你升級一些 Plugin 就完全能夠解決問題了,并且這些 warning 現(xiàn)階段并不會對你的構(gòu)建產(chǎn)生什么破壞性的影響,以下我們提供了一些我們實踐中沉淀的參考:
升級 terser-webpack-plugin 能解決的 Warning:
Compilation.cache was removed
optimizeChunkAssets
升級 mini-css-extract-plugin 能夠解決的 warning:
MainTemplate.hooks.renderManifest
ChunkTemplate.hooks.renderManifest
MainTemplate.hooks.hashForChunk
Module.id: Use new ChunkGraph API
Module.updateHash
Chunk.modulesIterable
MainTemplate.outputOptions
MainTemplate.renderCurrentHashCode
MainTemplate.getAssetPath
MainTemplate.requireFn
ChunkGroup.getModuleIndex2 was renamed to getModulePostOrderIndex
做好了前面這些準(zhǔn)備之后,我們就可以直接升級一把梭:
npm?install?webpack@latest?--dev
接下來,就可以開始嘗試令人心動的 Webpack5 啦~
踩坑日記
生態(tài)對齊 Webpack5
如果你的項目升級了 Webpack5 之后直接在項目中啟動構(gòu)建或者 devServer,你一般會收到類似下面這樣的報錯信息:
TypeError:?Cannot?add?property?htmlWebpackPluginAlterChunks,?object?is?not?extensible
????at?/path/to/node_modules/html-webpack-plugin/index.js:59:56
如果是 Webpack 老司機(jī)應(yīng)該就會一眼發(fā)現(xiàn)這個問題的關(guān)鍵所在 —— html-webpack-plugin,打開 Plugin 的 Github 首頁[4],解決方案就擺在你的眼前了:

同理,一般在控制臺如果有拋出 error 或者 warning,大多都能通過升級對應(yīng)依賴的版本解決問題,Webpack5 的升級還是要比當(dāng)年 Webpack4 的升級來得絲滑許多,并且社區(qū)上的生態(tài)也在逐步跟進(jìn)和完善。
這里再舉幾個比較常見的例子,比如我們常用來支撐 serviceWorker 的 workbox-webpack-plugin,因為它內(nèi)部也依賴了 Webpack 的核心事件以及一些 API,因此也需要進(jìn)行升級,這里可以參考:https://github.com/GoogleChrome/workbox/issues/2669;還有我們平時用來壓縮 CSS 的 optimize-css-assets-webpack-plugin[5],在 Plugin Github 首頁中也明確表示了在 Webpack5 之后優(yōu)先使用 Webpack 官方出品的 css-minimizer-webpack-plugin[6]。

當(dāng)然,還有一些其他生態(tài)對齊的點就不在這個文檔里再做贅述了,大部分內(nèi)容你都可以在官網(wǎng)介紹[1]以及升級手冊[2]這兩份官方文檔中找到,并且,如果有一些需要 case by case 去解決的通用問題,社區(qū)上大多也已經(jīng)有 issue 或者其他文檔中可以發(fā)現(xiàn)線索,當(dāng)然,如果被你發(fā)現(xiàn)了一些“待解決”的問題,不也正是你向開源社區(qū)貢獻(xiàn)力量的機(jī)會嘛~
基本上完成了上面這些依賴的升級,你的項目就能通過 Webpack5 跑起來了。
PS:optimize-css-assets-webpack-plugin[5] 這插件既沒有 cache 又沒有 parallel,就我而言,我寧可在 loader 里使用 cssnano 做 CSS 邏輯優(yōu)化,也不愿意在這個插件上無奈地浪費生命 ??,但是 css-minimizer-webpack-plugin[6] 解救了強(qiáng)迫癥的我,它真的是再好不過的選擇了。
一碰就掛的 HMR
由于 webpack-dev-server 依賴了很多 Webpack 構(gòu)建配置,所以在升級之后,不免有些地方?jīng)]有對接地那么絲滑,HMR 就是一個最形象的例子,它變得十分脆弱,往往在不知不覺中,你會突然發(fā)現(xiàn),這東西咋沒反應(yīng)了?!
我的第一直覺是認(rèn)為自己是不是忽略了什么 devServer 的配置,但我不是照著官方文檔 CV 的嘛?!冷靜下來后我點開了 Google,果然,社區(qū)上早有前人遇到了同樣的問題[7]。
這里我就長話短說了,這是 webpack-dev-server 遺留的一個 BUG,只有你在 Webpack 配置中顯式地設(shè)置了 target: 'web',HMR 才能夠生效,哪怕你通過數(shù)組的方式去設(shè)置 target,例如:target: \['web', 'es5'\],也會阻塞 HMR 的能力。
但好在官方發(fā)布了對接 Webpack5 的 v4 版本,你只需要通過升級 webpack-dev-server 至 next 版本(如果你在項目中通過它提供的 Node API 使用它的話),就能解決上述問題:

不過,因為截止 2020 年 1 月 28 日 webpack-dev-server v4 只發(fā)布了 beta0 一個 next 版本[8],所以還有些能力不太穩(wěn)定,比如你沒法通過 localhost 啟動你的項目[9],但是這些都只是細(xì)節(jié)問題了,不影響整體的功能完整跑通。
構(gòu)建時新特性
內(nèi)置靜態(tài)資源構(gòu)建能力 —— Asset Modules
Webpack 只會打包 JS 文件,如果要打包其它文件就需要加上相應(yīng)的 loader。
在 Webpack5 之前,我們一般都會使用以下幾個 loader 來處理一些常見的靜態(tài)資源,比如 PNG 圖片、SVG 圖標(biāo)等等,他們的最終的效果大致如下所示:
raw-loader:允許將文件處理成一個字符串導(dǎo)入 file-loader:將文件打包導(dǎo)到輸出目錄,并在 import 的時候返回一個文件的 URI url-loader:當(dāng)文件大小達(dá)到一定要求的時候,可以將其處理成 base64 的 URIS ,內(nèi)置 file-loader
Webpack5 提供了內(nèi)置的靜態(tài)資源構(gòu)建能力,我們不需要安裝額外的 loader,僅需要簡單的配置就能實現(xiàn)靜態(tài)資源的打包和分目錄存放。如下:滿足規(guī)則匹配的資源就能夠被存放在 assets 文件夾下面。
//?webpack.config.js
module.exports?=?{
????...,
????module:?{
??????rules:?[
??????????{
????????????test:?/\.(png|jpg|svg|gif)$/,
????????????type:?'asset/resource',
????????????generator:?{
????????????????//?[ext]前面自帶"."
????????????????filename:?'assets/[hash:8].[name][ext]',
????????????},
????????},
??????],
????},
}
其中 type 取值如下幾種:
asset/source ——功能相當(dāng)于 raw-loader。 asset/inline——功能相當(dāng)于 url-loader,若想要設(shè)置編碼規(guī)則,可以在 generator 中設(shè)置 dataUrl。具體可參見官方文檔[10]。 asset/resource——功能相當(dāng)于 file-loader。項目中的資源打包統(tǒng)一采用這種方式,得益于團(tuán)隊項目已經(jīng)完全鋪開使用了 HTTP2 多路復(fù)用的相關(guān)特性,我們可以將資源統(tǒng)一處理成文件的形式,在獲取時讓它們能夠并行傳輸,避免在通過編碼的形式內(nèi)置到 js 文件中,而造成資源體積的增大進(jìn)而影響資源的加載。 asset—— 默認(rèn)會根據(jù)文件大小來選擇使用哪種類型,當(dāng)文件小于 8 KB 的時候會使用 asset/inline,否則會使用 asset/resource。也可手動進(jìn)行閾值的設(shè)定,具體可以參考官方文檔[11]。
內(nèi)置 FileSystem Cache 能力加速二次構(gòu)建
Webpack5 之前,我們會使用 cache-loader[12] 緩存一些性能開銷較大的 loader ,或者是使用 hard-source-webpack-plugin[13] 為模塊提供一些中間緩存。在 Webpack5 之后,默認(rèn)就為我們集成了一種自帶的緩存能力(對 module 和 chunks 進(jìn)行緩存[14])。通過如下配置,即可在二次構(gòu)建時提速。
//?webpack.config.js
module.exports?=?{
????...,
????cache:?{
????????type:?'filesystem',
????????//?可選配置
????????buildDependencies:?{
????????????config:?[__filename],??//?當(dāng)構(gòu)建依賴的config文件(通過?require?依賴)內(nèi)容發(fā)生變化時,緩存失效
????????},
????????name:?'',??//?配置以name為隔離,創(chuàng)建不同的緩存文件,如生成PC或mobile不同的配置緩存
????????...,
????},
}
生產(chǎn)環(huán)境下默認(rèn)的緩存存放目錄在 node_modules/.cache/webpack/default-production 中,如果想要修改,可通過配置 name,來實現(xiàn)分類存放。如設(shè)置 name: 'production-cache' 時生成的緩存存放位置如下。

PS:如果你直接通過調(diào)用 Webpack compiler 實例的 run 方法執(zhí)行定制化構(gòu)建操作時,你可能會遇到構(gòu)建緩存最終沒有生成緩存文件的情況,在搜索了 Webpack 的相關(guān) Issues 后我們發(fā)現(xiàn),你還需要手動調(diào)用 compiler.close() 來輸出緩存文件。

內(nèi)置 WebAssembly 編譯及異步加載能力(sync/async)
WebAssembly[15] 被設(shè)計為一種面向 web 的二進(jìn)制的格式文件,以其更接近于機(jī)器碼而擁有著更小的文件體積和更快速的執(zhí)行效率。c/c++ 等高級語言都能直接編譯成 .wasm 文件而被 js 調(diào)用。Webpack4 本身就已經(jīng)集成了 WebAssembly 的加載能力,只不過在 Webpack5 拓展了 WebAssembly 的異步加載能力,使得我們可以更靈活地借助 WebAssembly 做更多有意思的事情。
借此機(jī)會,我們可以簡單介紹一下 WebAssembly 在實際項目開發(fā)中的快速上手流程:
以一個簡單的求和函數(shù)為例,除了按照官方文檔[16]生成 WebAssembly 文件外,我們可以通過 WasmFiddle[17] 這個在線網(wǎng)址來編寫 c/c++ 程序,再直接轉(zhuǎn)換為 WebAssembly 文件,并且該網(wǎng)站還為我們提供了即時的調(diào)試能力。

通過上述方式,我們能夠很快的得到一個 program.wasm 文件,將其下載到本地項目中,你便可以開始使用它了。
在 Webpack5 之前,我們會通過 wasm-loader 來進(jìn)行 WebAssembly 文件的處理,同時在使用時還需要通過如下示例代碼才能調(diào)用我們封裝在 wasm 里的函數(shù):
import?wasm?from?'/program.wasm';
wasm().then(instance?=>?{
??const?sum?=?instance.exports.sum;
??console.log(sum(1,?2));
}
這個過程勢必是重復(fù)繁瑣的,但是,通過 Webpack5 內(nèi)置的 WebAssembly 構(gòu)建能力,我們僅需要配置如下:
//?webpack.config.js
module.exports?=?{
????...,
????experiments:?{
????????asyncWebAssembly:?true,
????},
????module:?{
????????rules:?[
????????????...,
???????????{
????????????????test:?/\.wasm$/,
????????????????type:?'webassembly/async',
????????????},
?????????],
????},
}
而當(dāng)我們要使用 wasm 的時候,就是如此簡單:
import?{?sum?}?from?'./program.wasm'
console.log(sum(1,?2))
內(nèi)置 Web Worker 構(gòu)建能力
Web Worker 為 Web 內(nèi)容在后臺線程中運行腳本提供了一種簡單的方法。線程可以執(zhí)行任務(wù)而不干擾用戶界面。通常,我們可以將一些加解密或者圖片處理等一些比較復(fù)雜的算法置于子線程中,當(dāng)子線程執(zhí)行完畢之后,再向主線程通信。
假如我們有一個比較耗時的計算邏輯存放在 calc.js 文件中,當(dāng)我們執(zhí)行完成之后,通過 postMessage 將文件信息通知給主線程。
//??calc.worker.js
let?num;
for?(let?i?=?0;?i?<=?20000000;?i++)?{
??if?(i?===?20000000)?{
????num?=?20000000;
??}
}
postMessage({
??value:?num,
});
master.js 主線程監(jiān)聽子線程的消息,當(dāng)收到消息傳輸過來的時候,執(zhí)行一些相應(yīng)的操作。
//?master.js
worker.onmessage?=?e?=>?{
??console.log(e.data.value);
};
對于以前在處理 Web Worker 的時候,我們需要借助于 worker-loader 來處理,通過如下配置
//?webpack.config.js
module.exports?=?{
????...,
?????module:?{
????????rules:?[
????????????{
????????????????test:?/\.worker\.js$/,
????????????????use:?{?loader:?'worker-loader'?},
????????????},
????????],
????},
}
在使用的時候,直接引入 calc.worker.js 文件就能夠構(gòu)造一個 Worker 對象,因此主線程的處理如下:
//?master.js
import?Worker?from?'./calc.worker.js';
const?worker?=?new?Worker();
worker.onmessage?=?e?=>?{
??console.log(e.data.value);
};
在 Webpack5 中,我們不需要添加 loader 的處理方式,并且不需要針對 worker 配置特定的 .worker.js 之類的文件名,借助于 new URL, 便能實現(xiàn) worker 的創(chuàng)建。如下,亦可參考官方示例[18]:
//?master.js
const?worker?=?new?Worker(new?URL('./calc.js',?import.meta.url),?{
????name:?"calc"
??/*?webpackEntryOptions:?{?filename:?"workers/[name].js"?}?*/
});
worker.onmessage?=?e?=>?{
??console.log(e.data.value);
};
但因為考慮到開發(fā)者對于編程的習(xí)慣和方便性,我們此次并未將 worker-loader 全量下掉,你還是可以直接通過 import 一個 .worker.js 后綴的來使用 web worker ;同時,你也可以使用上述 Webpack5 的新特性,但是請注意,在new URL()中不能使用.worker.js命名文件,否則會優(yōu)先被 worker-loader 解析而導(dǎo)致最終你的 worker 無法正常運行。
運行時新特性
移除了 Node.js Polyfills,Polyfill 交由開發(fā)者自由控制
由于移除了 Node.js Polyfills,如果前端包里使用了 process、path 這些依賴,需要手動添加 Polyfill 支持。如前面準(zhǔn)備工作介紹的 process 等。
以 react-markdown 為例,當(dāng)我們的項目升級到 Webpack5 之后,就會報錯提示 process.cwd is not a function,如果你在項目里也遇到了類似的情況,比如某個你熟悉的 nodejs API[19] 在控制臺報錯 is not defined,這時候就需要我們自行添加相關(guān)的 Browser Polyfill,因為 Webpack5 不會再幫你處理這些 polyfill 了。process 的詳細(xì)配置可參考準(zhǔn)備工作。

資源打包策略更優(yōu),構(gòu)建產(chǎn)物更“輕量”
Prepack 是 Facebook 開源的一個 JavaScript 代碼優(yōu)化工具,運行在 “編譯” 階段,生成優(yōu)化后的代碼。下面是 Prepack 官網(wǎng)上的一個示例,我們可以看到,在對于任何輸入,函數(shù)都能得到一個固定輸出的時候,Prepack 就能在編譯時,將結(jié)果幫我們計算出來。對于一些復(fù)雜且固定的計算邏輯而言,這種“預(yù)計算”能力,既能減小我們包的體積,又能加快運行時的速度。如官方示例[20]所示:

Webpack5 內(nèi)置了 Prepack 的部分能力,能夠在極致之上,再度優(yōu)化你的項目產(chǎn)物體積:

深度 Tree Shaking 能力支持
Tree Shaking 能力,是指能夠在打包的過程中移除 JavaScript 上下文中未被引用到的變量,借以次來減少打包后的體積。比如我們在開發(fā)階段,引入某個文件時,被引用的文件中存在部分沒有用到的代碼、或是在開發(fā)的時候忘記刪掉、亦或是前面開發(fā)者遺留下來的代碼但是不便大膽的做一些刪減工作,有了 Tree Shaking 這個功能之后,這些都將不在是問題,Webpack 在打包的時候能夠自動幫我們完成沒使用到的代碼的刪除工作,特別是 Webpack5 能夠支持深層嵌套的 export 的 Tree Shaking,具體可參考官網(wǎng)[21]給出的示例:

以上述為例,在 Webpack5 的能力下,配合上面我們提到的類 Prepack 能力,那些冗余的代碼就自動被清除了:

所以,你還需要擔(dān)心項目里會有冗余代碼對你的線上包體積造成負(fù)擔(dān)嗎?
更友好的 Long Term Cache 支持性,chunkid 不變
Webpack5 之前,文件打包后的名稱是通過 ID 順序排列的,一旦后續(xù)有一個文件進(jìn)行了改動,那么必將造成后面的文件打包出來的文件名產(chǎn)生變化,即使文件內(nèi)容沒有產(chǎn)生改變。因此會造成資源的緩存失效。
Webpack5 有著更友好的長期緩存能力支持,其通過 hash 生成算法,為打包后的 modules 和 chunks 計算出一個短的數(shù)字 ID ,這樣即使中間刪除了某一個文件,也不會造成大量的文件緩存失效,具體介紹可參見官網(wǎng)[22]。
例如,我們在項目中新增一個頁面,然后對比 Webpack4 和 Webpack5 打包后的產(chǎn)物名稱的變化:
Webpack4:在首位產(chǎn)生的一個新的 chunk 將會導(dǎo)致所有 js 文件緩存失效,我們可以通過 sourcemap 內(nèi)容看出,其實兩個名稱完全不同的 JS 文件,指向的始終是一份源文件。

Webpack5:僅對有修改的文件失效

這里還需要額外拓展一下,Webpack5 還使用了真實的 contenthash[23] 來支持更友好的 Long term cache,啥意思呢,就是如果你的邏輯里只是刪了下注釋或者改了個變量名,那本質(zhì)上你的代碼邏輯是沒有發(fā)生變化的,所以對于壓縮后的文件這些內(nèi)容的變更不會導(dǎo)致 contenthash 變化。
支持 Top Level Await,從此告別 async
Webpack5 還支持 Top Level Await。即允許開發(fā)者在 async 函數(shù)外部使用 await 字段。它就像巨大的 async 函數(shù),原因是 import 它們的模塊會等待它們開始執(zhí)行它的代碼,因此,這種省略 async 的方式只有在頂層才能使用。
通過開啟以下配置:
//?webpack.config.js
module.exports?=?{
????...,
????experiments:?{
????????topLevelAwait:?true,
????},
}
開啟前后對比,以我們的國際化項目中經(jīng)常用到的 i18n 拉取字典的邏輯為例:
//?開啟?top?level?await?之前
import?i18n?from?'XXX/i18n-utils'
(async?()?=>?{
??//?國際化文案異步初始化邏輯
??await?i18n.init({/*?...?*/})
??root.render(<AppContainer?/>)
})()
//?開啟?top?level?await?之后
import?i18n?from?'XXX/i18n-utils'
await?i18n.init({/*?...?*/})
root.render(<AppContainer?/>)
我們不再需要為我們的異步邏輯包裹 async IIFE 了,在 JS 邏輯頂層,我們就可以直接使用 await 來進(jìn)行異步邏輯的控制。
當(dāng)然,我們也可以將此特性用于異步導(dǎo)出或者引入模塊:
//?src/Home/index.jsx
import?React?from?'react';
const?Test?=?()?=>?{
??return?<div>123div>;
};
let?Home?=?null;
await?new?Promise(resolve?=>?{
??Home?=?Test;
??resolve();
});
export?default?Home;
//?src/index.jsx
import?Home?from?'./Home'
為了 eslint 語法檢測的支持,我們還需要添加 babel 插件 @babel/plugin-syntax-top-level-await 來讓我們的 babel 能夠識別 top level await 語法。
但是,不同于我們處理其他 ES6 語法的方式,我們并不能將 top level await 語法的編譯過程都收口在 Babel 中,就如下方的插件首頁截圖所述,此插件的作用僅僅是使得 babel 能夠解析這個新語法,并將它轉(zhuǎn)化為 AST,但并不會將其編譯掉,因此真正的編譯過程還是需要交給 Webpack 或者 Rollup 這樣的構(gòu)建工具來處理來處理的。

最終效果
為了展示 Webpack5 在打包構(gòu)建的過程中對于項目的收益,我們做了如下對比:
構(gòu)建效率對比
對于 filesystem 緩存開啟與否,我們針對部門的項目模版做了如下的對比實驗。可以看到,除了初次構(gòu)建話費時間相對長一點外,后續(xù)的二次構(gòu)建速度得到了大幅度的提高。
沒有配置時的初次和二次構(gòu)建:

配置了緩存的初次構(gòu)建和二次構(gòu)建:


Chunk 更新產(chǎn)物的緩存失效率對比
以我們在上述 Long Term Cache 特性中給出的打包后的 8 個 js chunk 資源為例。
Webpack4:在首位產(chǎn)生的一個新的 chunk 將會導(dǎo)致所有 js 文件緩存失效。

Webpack5:僅對有修改的文件失效


當(dāng)然,Webpack5 升級給項目帶來的最終增益還遠(yuǎn)遠(yuǎn)不止上面提到的這些,我們還需要收集更多的數(shù)據(jù)來驗證 Webpack5 的升級對運行時階段帶來的更深層次的性能收益,但就目前而言,Webpack5 的許多特性已經(jīng)能讓我們在開發(fā)階段舒適許多。
總結(jié)
Webpack5 雖然說為我們提供了很多優(yōu)秀的新特性,但是對于開發(fā)者在實際的開發(fā)過程中的改動感知還是比較弱的,我們可以很舒適地上手這些新特性,并且在升級過程中隨著 Webpack 體系生態(tài)的逐步完善,當(dāng)我們遇到問題時也都能夠很快找到明確的解決方案,所以,趕快一起體驗起來吧。
如果有同學(xué)也對 Webpack5 的相關(guān)能力感興趣,咱們也可以隨時交流討論哈~
招聘硬廣
我們團(tuán)隊招人啦!!!歡迎加入字節(jié)跳動商業(yè)變現(xiàn)前端團(tuán)隊,我們在做的技術(shù)建設(shè)有:前端工程化體系升級、團(tuán)隊 Node 基建搭建、前端一鍵式 CI 發(fā)布工具、組件服務(wù)化支持、前端國際化通用解決方案、重依賴業(yè)務(wù)系統(tǒng)微前端改造、可視化頁面搭建系統(tǒng)、商業(yè)智能 BI 系統(tǒng)、前端自動化測試等等等等,擁有近百號人的北上杭大前端團(tuán)隊,一定會有你感興趣的領(lǐng)域,如果你想要加入我們,歡迎點擊我們的內(nèi)推通道吧:
參考資料
[1]?https://webpack.js.org/blog/2020-10-10-webpack-5-release/#general-direction
[2]?https://webpack.js.org/migrate/5/
[3]?https://github.com/jantimon/html-webpack-plugin#webpack-5
[4]?https://github.com/jantimon/html-webpack-plugin
[5]?https://github.com/NMFR/optimize-css-assets-webpack-plugin
[6]?https://github.com/webpack-contrib/css-minimizer-webpack-plugin
[7]?https://github.com/webpack/webpack-dev-server/issues/2758
[8]?https://www.npmjs.com/package/webpack-dev-server
[9]?https://github.com/webpack/webpack-dev-server/issues/2934
[10]?https://webpack.js.org/guides/asset-modules/#custom-data-uri-generator
[11]?https://webpack.js.org/guides/asset-modules/#general-asset-type
[12]?https://github.com/webpack-contrib/cache-loader
[13]?https://github.com/mzgoddard/hard-source-webpack-plugin
[14]?https://webpack.js.org/configuration/other-options/#cache
[15]?https://webassembly.org/
[16]?https://webassembly.org/getting-started/developers-guide/
[17]?https://wasdk.github.io/WasmFiddle//
[18]?https://github.com/webpack/webpack/tree/master/examples/worker
[19]?https://nodejs.org/dist/latest-v14.x/docs/api/
[20]?https://prepack.io/
[21]?https://webpack.js.org/blog/2020-10-10-webpack-5-release/#major-changes-optimization
[22]?https://webpack.js.org/blog/2020-10-10-webpack-5-release/#major-changes-long-term-caching
[23]?https://webpack.js.org/blog/2020-10-10-webpack-5-release/#real-content-hash
