Webpack 5 異動

General Direction

  • Improve build performance with Persistent Caching.
  • Improve Long Term Caching with better algorithms and defaults.
  • Improve bundle size with better Tree Shaking and Code Generation.
  • Improve compatibility with the web platform.
  • Clean up internal structures that were left in a weird state while implementing features in v4 without introducing any breaking changes.
  • Prepare for future features by introducing breaking changes now, allowing us to stay on v5 for as long as possible.

Long Term Caching

Chunk, Module IDs and Export names deterministic

  • module, chunk ID: 3-5 碼的數字。
  • exports name: 2 碼字串。
{
	chunkIds: 'deterministic',
	moduleIds: 'deterministic',
	mangleExports: 'deterministic'
}

Real Content Hash

  • 使用真的 hash 值處理 [contenthash]

  • minimizing 後可能效果不明顯。

Development Support

Named Chunk IDs

使用人類可以看懂的方式命名 chunk id。

A Module ID is determined by its path, relative to the context. A Chunk ID is determined by the chunk's content.

一般情況下可以不用再使用 import(/* webpackChunkName: "name" */ "module") 來除錯。

Module Federation

  • 新功能;可以讓不同的 webpack build 合作無間。

  • 參考這份文件

New Web Platform Features

JSON Modules

  • 一定要有 default exports

  • named exportsstrict ECMAScript module 中不得使用。

import.meta

  • import.meta.webpackHot === module.hot
  • import.meta.webpack:當前 webpack 版本
  • import.meta.urlfile: URL

Asset modules

原生支援 assets module,可以透過以下語法存取 assets。

  • import url from './image.png':現行語法,需配合 module.rules 設定。
  • new URL('./image.png', import.meta.url):即使不進行 bundle 也可運行。

Native Worker support

  • 如果以 new URL('./worker.js', import.meta.url) 的語法使用 Worker,Webpack 會將其中的 js 檔視為 entry point。
  • new URL() 語法可以直接在 browser 中執行。

URIs

import fromData from 'data:text/javascript;export default 2020'
import fromFile from 'file://xxx.xxx.xxx'
import fromHttp from 'https://xxx.xxx.xxx'

Async Modules

可以透過以下語法使用 async module

  • import()
  • require():回傳 Promise

可以在以下情境使用

  • async externals
  • WebAssembly Module
  • ECMAScript Modules that are using Top-Level-Await

External

看不懂

New Node.js Ecosystem Features

  • 支援 package.json 中的 exportsimports 欄位。
  • 支援 Yarn PnP
  • 參考這份文件

Development Experience

Improved target

可以指定版本 ,例如target: ['web', 'es2020']target: 'node14'

Stats

不想看這段

Progress

原本用在 CLI --progress 指令的 ProgressPlugin 可以透過 plugin 設定。

  • 除了計次已經處理的 modules,現在也可以計次 entriesdependencies(預設值)。
  • 原本的進度 console 增加 500ms throttle。
  • profile mode 顯示槽狀 progress message。
  • percentBy: string 可以定義進度的計算方式

Automatic unique naming

如果同時存在複數個 webpack runtime, 預設以 package.jsonname 作為 output.uniqueName 的值。

Automatic public path

Typescript typings

Optimization

Nested tree-shake

b 會被移除

// inner.js
export const a = 1
export const b = 2

// module.js
export * as inner from './inner'

// user.js
import * as module from './module'

console.log(module.inner.a)

Inner-module tree-shake

optimization.innerGraphtrue 時,會將 printHellohello 標記為未被使用的 。

// inner.js
export function hola() {
  return 'hola'
}

export function hello() {
  return 'hello'
}

// module.js
import * as inner from './inner'

export function printHola() {
  console.log(inner.hola())
}

export function printHello() {
  console.log(inner.hello())
}

// app.js
import * as module from './module'

module.printHola()

optimization.sideEffectsfalse 時,會將 printHellohello 移除。

以下語法能夠被識別:

  • function declarations

  • class declarations

  • export default with or variable declarations with

  • function expressions

    • class expressions
    • sequence expressions
    • /*#__PURE__*/ expressions
    • local variables
    • imported bindings

CommonJs tree-shake

以下語法可以被識別:

  • 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

General Tree Shaking improvements

可以對 export * 進行 tree-shake

可以手動使用 /* webpackExports: ["abc", "default"] */import() 進行 tree-shake

Improved Code Generation

以下編譯後語法簡化:

BeforeAfter
Object(...)Object(0, ...)
r.d(x, 'a', () => a);r.d(x, 'b', () => b);r.d(x, {a: () => a, b: () => b})

可以透過 output.environment 或是 target 來設定哪些 ECMAScript 功能/語法可以使用。