1. 程式人生 > >Webpack 4 不完全遷移指北

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

覺得本文對你有幫助?請分享給更多人

關注「前端大全」,提升前端技能

640?wx_fmt=png