Webpack 4 不完全遷移指北
(點選上方公眾號,可快速關注)
來源:dwqs
https://github.com/dwqs/blog/issues/60
在 webpack 3 釋出 之後, webpack 團隊向社群承諾,之後 webpack 主版本的迭代會有一個時間比較長且穩定的開發週期。而在2017年8月份的時候,webpack 團隊從 master 分支切出了 next 分支用於 webpack 4 的開發,經歷 5 個月的開發週期之後,webpack 4.0-beta 在 2018年1月 已經 Released 了,不僅兌現了之前的承諾,還帶來了諸多新特性,在使用者使用的體驗上也作了諸多改進。
安裝
如果需要使用 webpack 4,則需要從 next 分支上安裝:
// yarn
yarn add webpack@next webpack-cli --dev
// npm
npm install webpack@nextwebpack-cli --save-dev
不完全遷移指北
環境
不再支援 Node.js 4。
根據 package.json 配置, Node.js 的最低支援版本為 6.11.5
模組型別
webpack 4之前,js 是 webpack 中的唯一模組型別,因而不能有效地打包其它型別的檔案。而 webpack 4 則提供了 5 種模組型別:
javascript/auto: (webpack 3中的預設型別)支援所有的JS模組系統:CommonJS、AMD、ESM
javascript/esm: EcmaScript 模組,在其他的模組系統中不可用(預設 .mjs 檔案)
javascript/dynamic: 僅支援 CommonJS & AMD,EcmaScript 模組不可用
json: 可通過 require 和 import 匯入的 JSON 格式的資料(預設為 .json 的檔案)
webassembly/experimental: WebAssembly 模組(處於試驗階段,預設為 .wasm 的檔案)
此外,webpack 4 中會預設解析 .wasm, .mjs, .js 和 .json 為字尾的檔案。
在對應檔案的 loader 配置,需要增加 type 欄位來指定模組型別:
module: {
rules: [{
test: /\.special\.json$/,
type: "javascript/auto",
use: "special-loader"
}]
}
javascript/auto / javascript/esm 都可以處理 ESM, 但後者會更加嚴格:
匯入的名稱必須存在於匯入的模組中
動態的模組(非 ESM,如 CommonJS)只能通過預設 import 匯入,其它方式(包括名稱空間)的匯入都會報錯
對於 WebAssembly 模組:
可以匯入其它模組(JS 和 WASM)
試圖在 WASM 模組中匯入不存在的模組將會得到一個警告或者錯誤
ESM 可以引入 WASM 模組中匯出的模組名
僅可在 async chunks(通過 import() 匯入的模組)中使用,在 initial chunks 中是無效的(不利於提升 web 應用的效能)
import(): 動態匯入
在 webpack 4 中,import() 會返回一個帶名稱空間(namespace)的物件,這對 ES Module 不會有影響,但對於遵循 commonjs 規範的模組則會加一層包裹:
// webpack 2/3
import("./commonjs").then(exports => {
...
})
// webpack 4
import("./commonjs").then({default: exports}=> {
...
})
mode: 模式配置
mode 是 webpack 4 中新增加的引數選項,其有兩個可選值:production 和 development。mode 不可預設,需要二選一:
production 模式:
預設提供所有可能的優化,如程式碼壓縮/作用域提升等
不支援 watching
process.env.NODE_ENV 的值不需要再定義,預設是 production
/** webpack.production.config.js **/
// webpack 2/3
module.exports = {
plugins: [
newUglifyJsPlugin(/* ... */),
newwebpack.DefinePlugin({"process.env.NODE_ENV": JSON.stringify("production")}),
newwebpack.optimize.ModuleConcatenationPlugin(),
newwebpack.NoEmitOnErrorsPlugin()
]
}
// webpack 4
module.exports = {
mode: 'production'
}
development 模式:
主要優化了增量構建速度和開發體驗
process.env.NODE_ENV 的值不需要再定義,預設是 development
開發模式下支援註釋和提示,並且支援 eval 下的 source maps
/** webpack.development.config.js **/
// webpack 2/3
module.exports = {
plugins: [
newwebpack.NamedModulesPlugin(),
newwebpack.DefinePlugin({"process.env.NODE_ENV": JSON.stringify("development")})
]
}
// webpack 4
module.exports = {
mode: 'development'
}
此外, webpack 4 還提供一種隱藏(none)模式,這種模式下會禁用一切優化
sideEffects 設定
webpack 4 在 package.json 中引入了對 sideEffects: false 的支援。當模組的 package.json 中新增該欄位時,表明該模組沒有副作用,也就意味著 webpack 可以安全地清除被用於重複匯出(re-exports)的程式碼。
JSON
webpack 4 不僅支援本地處理 JSON,還支援對 JSON 的 Tree Shaking。當使用 ESM 語法 import json 時,webpack 會消除掉JSON Module 中未使用的匯出。
此外,如果要用 loader 轉換 json 為 js,需要設定 type 為 javascript/auto:
module.rules: [
{
test: /\.special\.json$/,
type: "javascript/auto",
use: "special-loader"
}
]
配置
刪除了一些常用內建外掛:
NoEmitOnErrorsPlugin -> optimization.noEmitOnErrors (生產模式預設)
ModuleConcatenationPlugin -> optimization.concatenateModules (生產模式預設)
NamedModulesPlugin -> optimization.namedModules (開發模式預設)。
刪除了 CommonsChunkPlugin,取而代之的是 optimization.splitChunks 和 optimization.runtimeChunk,這提供了細粒度的快取策略控制
可以使用 module.rules[].resolve 來配置解析,它會與全域性配置合併。
optimization.minimize 用於控制 minimizing 的開關。 生產模式預設為開,開發模式預設為關。
optimization.minimizer 用於配置 minimizers 和選項。
許多支援佔位符(placeholders)的配置選項現也支援函式形式
錯誤的 options.dependencies 配置將報錯
sideEffects 可以通過 module.rules 覆蓋
output.hashFunction 可以是一個建構函式,用於自定義 hash 函式。處於效能考慮,也可以提供非加密雜湊函式
output.globalObject 可以用於配置執行時的全域性物件引用
預設配置
webpack 預設會按照 .wasm, .mjs, .js 和 .json 的副檔名順序查詢模組。
output.pathinfo 在開發模式下預設是開啟的
生產環境下,預設關閉記憶體快取
entry 的預設值是 ./src,output.path 的預設值是 ./dist
在選擇模式選項時,預設值是 production
優化
uglifyjs-webpack-plugin 釋出 v1,支援 ES2015
使用 JSONP 陣列來代替 JSONP 函式 –> 非同步支援
webpack 自身也可以刪除無用程式碼。webpack 2/3 中是在 Uglify 時刪除無用程式碼,webpack 4 中 webpack 也可以(在某些情況下)刪除無用程式碼,避免 import() 引用無用程式碼時導致的奔潰
作用域提升後的模組將生成更少的程式碼
效能
預設情況,UglifyJS 會預設快取和並行化(完全實現快取和並行化將在 webpack 5 中實現)
多個性能改進,尤其是在增量構建這方面
改進了 RemoveParentModluesPlugin 的效能
未使用模組不再有非必要的作用域提升
新增 ProfilingPlugin,此外掛會(在 Chrome 瀏覽器中)建立一個包含各外掛時間消耗的檔案
for of 代替 forEach;Map/Set 代替 Objects;includes 代替 indexOf
同一個任務只會進入佇列一次
完整的效能改善和優化列表可以參考 Release 4.0-beta.0
移除的功能
移除了 module.loaders
移除了 loaderContext.options
移除了 Compilation.notCacheable
移除了 NoErrorsPlugin
移除了 Dependency.isEqualResource
移除了 NewWatchingPlugin
移除了 CommonsChunkPlugin
相關資源
webpack 4 beta — try it today!
webpack 4-beta.0
官方遷移草案
webpack 4: mode and optimization
覺得本文對你有幫助?請分享給更多人
關注「前端大全」,提升前端技能