Webpack5更新指南
2020-10-10 Webpack5 正式 realease 相較于 Webpack4 已經(jīng)過(guò)了兩年多了.在這期間并沒(méi)有什么重大的改變境肾,因?yàn)橥瑢W(xué)們并不喜歡重大的改變尤其是像 Webpack 這種你一年可能就用兩次. 但由于沒(méi)有去做一些重大的改變,我們不能去做一些重要的 api 和
架構(gòu)上的改變來(lái)提升效率粟按,所以 Webpack5 出現(xiàn)了.
這次主要在這幾點(diǎn)上:
- Improve build performance with Persistent Caching (通過(guò)使用持久性緩存來(lái)提高構(gòu)建性能)
- Improve Long Term Caching with better algorithms and defaults.(通過(guò)算法和默認(rèn)設(shè)置來(lái)提升長(zhǎng)期緩存)
- Improve bundle size with better Tree Shaking and Code Generation.(通過(guò)更好的 Tree Shaking 和代碼生成來(lái)壓縮包大小)
- Improve compatibility with the web platform. (提升網(wǎng)絡(luò)平臺(tái)的兼容性)
- Clean up internal structures that were left in a weird state while implementing features in v4 - without introducing any breaking changes.(清除一些內(nèi)部架構(gòu)祈争,這些架構(gòu)在v4版本中很奇怪.但并不會(huì)引起重大的改變)
- Prepare for future features by introducing breaking changes now, allowing us to stay on v5 for as long as possible. (為了以后的release健霹,我們現(xiàn)在引入了一些重大的改變速警,使我們可以在v5停留盡可能長(zhǎng)的時(shí)間)
既然官方都說(shuō)了要待一段時(shí)間我們就好好學(xué)吧,反正早用早享受G况7尴睢!
我們先從這幾個(gè)重大的變化娓娓道來(lái)
Improve build performance with Persistent Caching
Webpack5官方并沒(méi)有將 Persistent Caching作為默認(rèn)設(shè)置,而是需要我們?nèi)ヅ渲?因?yàn)閃ebpack5更主張安全而不是效率.不希望因?yàn)樘嵘?5%的表現(xiàn)而導(dǎo)致5%的出錯(cuò).
當(dāng)我們?cè)O(shè)置cache.type為 filesystem時(shí) 相對(duì)于webpack4 我們多了以下幾點(diǎn)轩触。
buildDependencies
buildDependencies指定構(gòu)建過(guò)程的代碼依賴性.讓webpack負(fù)責(zé)解析和遵循指定值的依賴項(xiàng).
官方推薦設(shè)置為 [__filename].
[__filename] depends在你的config文件.
當(dāng)你任何使用require()的module發(fā)生改變時(shí)Persistent Caching就會(huì)無(wú)效.
module.exports = {
cache: {
buildDependencies: {
// This makes all dependencies of this file - build dependencies
config: [__filename]
// By default webpack and loaders are build dependencies
}
}
};
如果是類(lèi)似fs.readFile的話就不會(huì)
version
一些build的依賴是不能壓縮成文件的像從數(shù)據(jù)庫(kù)讀取數(shù)據(jù)或者環(huán)境變量.對(duì)于這些值我們可以使用version
我們可以通過(guò)傳遞不一樣的string來(lái)使Persistent Caching無(wú)效
如果你的config讀取環(huán)境變量GIT_REV并且使用DefinePlugin來(lái)嵌入打包. 我們就可以將GIT_REV作為依賴.
僅當(dāng)將cache.type設(shè)置為filesystem時(shí)寞酿,cache.version才有意義
cache: {
version: `${process.env.GIT_REV}`
}
name
傳送門(mén)
cache的名字,不同的名字將會(huì)導(dǎo)致不同的共存緩存脱柱。當(dāng)具有多個(gè)應(yīng)該具有獨(dú)立緩存的配置時(shí)伐弹,使用cache.name才有意義
僅當(dāng)將cache.type設(shè)置為filesystem時(shí),cache.name才有意義
store
傳送門(mén)
cache.store告訴了webpack什么時(shí)候存儲(chǔ)data在filesystem
'pack':當(dāng)編譯器空閑時(shí)榨为,將所有緩存項(xiàng)的數(shù)據(jù)存儲(chǔ)在單個(gè)文件中
僅當(dāng)將cache.type設(shè)置為filesystem時(shí)惨好,cache.store選項(xiàng)才可用
module.exports = {
//...
cache: {
type: 'filesystem',
store: 'pack'
}
};
cacheDirectory
傳送門(mén)
緩存的基本目錄 默認(rèn)node_modules/.cache/webpack
僅當(dāng)將cache.type設(shè)置為filesystem時(shí),cache.cacheDirectory選項(xiàng)才可用
最終路徑為cache.directory + cache.name
const path = require('path');
module.exports = {
//...
cache: {
type: 'filesystem',
cacheDirectory: path.resolve(__dirname, '.temp_cache')
}
};
cacheLocation
傳送門(mén)
cache路徑 默認(rèn)path.resolve(cache.cacheDirectory, cache.name).
僅當(dāng)將cache.type設(shè)置為filesystem時(shí)柠逞,cache.cacheLocation才可用
const path = require('path');
module.exports = {
//...
cache: {
type: 'filesystem',
cacheLocation: path.resolve(__dirname, '.test_cache')
}
};
Improve Long Term Caching with better algorithms and defaults.
確定的 Chunk昧狮、模塊 ID 和導(dǎo)出名稱(chēng)
這些是自動(dòng)加入生產(chǎn)模式的
chunkIds: "deterministic" moduleIds: "deterministic" mangleExports: "deterministic"
該算法以確定性方式為modules和chunks 分配短(3或5位數(shù)字)數(shù)字ID,并為導(dǎo)出分配短(2個(gè)字符)名稱(chēng)板壮。這是包大小和長(zhǎng)期緩存之間的折衷方案逗鸣。
真正的content hash
之前只是使用內(nèi)部結(jié)構(gòu)的哈希值。當(dāng)只有注釋被修改或變量被重命名時(shí)绰精,這對(duì)長(zhǎng)期緩存會(huì)有積極影響撒璧。這些變化在壓縮后是不可見(jiàn)的。
Improve bundle size with better Tree Shaking and Code Generation.(通過(guò)更好的 Tree Shaking 和代碼生成來(lái)壓縮包大斜渴埂)
嵌套的 tree-shaking
傳送門(mén)
webpack 現(xiàn)在能夠跟蹤對(duì)導(dǎo)出的嵌套屬性的訪問(wèn)卿樱。這可以改善重新導(dǎo)出命名空間 對(duì)象時(shí)的 Tree Shaking(清除未使用的導(dǎo)出和混淆導(dǎo)出)。
// inner.js
export const a = 1;
export const b = 2;
// module.js
export * as inner from './inner';
// or import * as inner from './inner'; export { inner };
// user.js
import * as module from './module';
console.log(module.inner.a);
在生產(chǎn)模式時(shí)硫椰,b會(huì)被刪除
內(nèi)部模塊的 tree-shaking
webpack 4 沒(méi)有分析模塊的導(dǎo)出和引用之間的依賴關(guān)系繁调。webpack 5 有一個(gè)新的選項(xiàng) optimization.innerGraph,在生產(chǎn)模式下是默認(rèn)啟用的靶草,它可以對(duì)模塊中的標(biāo)志進(jìn)行分析蹄胰,找出導(dǎo)出和引用之間的依賴關(guān)系。
import { something } from './something';
function usingSomething() {
return something;
}
export function test() {
return usingSomething();
}
innerGraph會(huì)找出 something 只有在使用 test 導(dǎo)出時(shí)才會(huì)使用奕翔。這允許將更多的出口標(biāo)記為未使用裕寨,并從代碼包中省略更多的代碼。
當(dāng)設(shè)置"sideEffects": false時(shí)派继,可以省略更多的模塊宾袜。在這個(gè)例子中,當(dāng) test 導(dǎo)出未被使用時(shí)驾窟,./something 將被省略庆猫。
要獲得未使用的導(dǎo)出信息,需要使用 optimization.unusedExports绅络。要?jiǎng)h除無(wú)副作用的模塊阅悍,需要使用optimization.sideEffects好渠。可以分析以下標(biāo)記:
- 函數(shù)聲明
- 類(lèi)聲明
- 默認(rèn)導(dǎo)出export default 或定義變量以下的:
- 函數(shù)表達(dá)式
- 類(lèi)表達(dá)式
- 順序表達(dá)式
- /#PURE/ 表達(dá)式
- 局部變量
- 引入的捆綁(bindings)
使用 eval() 將為一個(gè)模塊放棄這個(gè)優(yōu)化节视,因?yàn)榻?jīng)過(guò) eval 的代碼可以引用范圍內(nèi)的任何標(biāo)記拳锚。這種優(yōu)化也被稱(chēng)為深度范圍分析。
CommonJs Tree的 Shaking
傳送門(mén)
webpack used to opt-out from used exports analysing for CommonJs exports and require() calls.
webpack 5 增加了 一些CommonJs 構(gòu)造的支持寻行,允許消除未使用的 CommonJs 導(dǎo)出霍掺,并從 require() 調(diào)用中跟蹤引用的導(dǎo)出名稱(chēng)。
以下結(jié)構(gòu)是支持的:
- exports|this|module.exports.xxx = ...
- exports|this|module.exports = require("...") (reexport)
- exports|this|module.exports.xxx = require("...").xxx (reexport)
- Object.defineProperty(exports|this|module.exports, "xxx", ...)
- require("abc").xxx
- require("abc").xxx()
- importing from ESM
- require() a ESM
- flagged exportType (special handling for non-strict ESM import):
- Object.defineProperty(exports|this|module.exports, "__esModule", { value: true|!0 })
- exports|this|module.exports.__esModule = true|!0
- It's planned to support more constructs in future
當(dāng)檢測(cè)到不可分析的代碼時(shí)拌蜘,webpack 會(huì)放棄杆烁,并且完全不跟蹤這些模塊的導(dǎo)出信息(為了性能考慮)。
一般的Tree Shaking提升
傳送門(mén)
export * 已得到改進(jìn)简卧,可以跟蹤更多信息兔魂,并且不再將默認(rèn)導(dǎo)出標(biāo)記為已使用。
export * 當(dāng)webpack確定出口沖突時(shí)举娩,將顯示警告析校。
import()允許通過(guò)/ * webpackExports:[“ abc”,“ default”] * /魔術(shù)注釋來(lái)手動(dòng)tree shake铜涉。
Improve compatibility with the web platform.
webpack 5停止了nodejs中的polyfill并且專(zhuān)注于前端兼容模塊智玻。
我們的目標(biāo)是提高與Web平臺(tái)的兼容性,在Web平臺(tái)上芙代,Node.js核心模塊不可用吊奢。
參考文檔:
introducing-federated-modules-in-webpack-5
module-federation-guide-offical
persistent-caching-guide-offical
webpackv5-realease-changelog
精讀module-federation