From 6c2ecd1b3add0b79e995ca68ac76863217cbabcc Mon Sep 17 00:00:00 2001 From: Hai Date: Tue, 8 Sep 2026 22:44:26 +0800 Subject: [PATCH 1/2] docs: correct outdated guides and inaccurate statements --- src/content/guides/asset-modules.mdx | 6 +-- src/content/guides/caching.mdx | 4 +- src/content/guides/development-vagrant.mdx | 8 ++-- src/content/guides/ecma-script-modules.mdx | 18 +++++---- src/content/guides/hot-module-replacement.mdx | 2 +- src/content/guides/lazy-loading.mdx | 3 +- src/content/guides/native-css.mdx | 28 +++++++------- src/content/guides/native-html.mdx | 34 ++++++++--------- src/content/guides/package-exports.mdx | 20 +++++----- src/content/guides/shimming.mdx | 10 ++--- src/content/guides/tree-shaking.mdx | 38 +++++++++++-------- 11 files changed, 88 insertions(+), 83 deletions(-) diff --git a/src/content/guides/asset-modules.mdx b/src/content/guides/asset-modules.mdx index abb97c612151..744701cd52ac 100644 --- a/src/content/guides/asset-modules.mdx +++ b/src/content/guides/asset-modules.mdx @@ -147,7 +147,7 @@ All `.png` files will be emitted to the output directory and their paths will be ### Custom output filename -By default, `asset/resource` modules are emitting with `[hash][ext][query]` filename into output directory. +By default, `asset/resource` modules are emitting with `[hash][ext][query][fragment]` filename into output directory. You can modify this template by setting [`output.assetModuleFilename`](/configuration/output/#outputassetmodulefilename) in your webpack configuration: @@ -372,10 +372,10 @@ new URL( // target: webworker new URL(`${__webpack_public_path__}logo.svg`, self.location); -// target: node, node-webkit, nwjs, electron-main, electron-renderer, electron-preload, async-node +// target: node, node-webkit, nwjs, electron-main, electron-preload, async-node new URL( `${__webpack_public_path__}logo.svg`, - require("node:url").pathToFileUrl(__filename), + require("node:url").pathToFileURL(__filename), ); ``` diff --git a/src/content/guides/caching.mdx b/src/content/guides/caching.mdx index d64ac6dac844..3af63080a329 100644 --- a/src/content/guides/caching.mdx +++ b/src/content/guides/caching.mdx @@ -256,13 +256,13 @@ Running another build, we would expect only our `main` bundle's hash to change, ... ``` -... we can see that all three have. This is because each [`module.id`](/api/module-variables/#moduleid-commonjs) is incremented based on resolving order by default. Meaning when the order of resolving is changed, the IDs will be changed as well. To recap: +... we can see that all three have. This happens when each [`module.id`](/api/module-variables/#moduleid-commonjs) is assigned from the resolving order (`optimization.moduleIds: 'natural'`), which webpack 5 only does by default for `mode: 'none'`. Meaning when the order of resolving is changed, the IDs will be changed as well. To recap: - The `main` bundle changed because of its new content. - The `vendor` bundle changed because its `module.id` was changed. - And, the `runtime` bundle changed because it now contains a reference to a new module. -The first and last are expected, it's the `vendor` hash we want to fix. Let's use [`optimization.moduleIds`](/configuration/optimization/#optimizationmoduleids) with `'deterministic'` option: +The first and last are expected, it's the `vendor` hash we want to fix. `production` mode already defaults [`optimization.moduleIds`](/configuration/optimization/#optimizationmoduleids) to `'deterministic'` and `development` mode to `'named'`, both stable across builds; setting `'deterministic'` explicitly keeps the ids stable regardless of `mode`: **webpack.config.js** diff --git a/src/content/guides/development-vagrant.mdx b/src/content/guides/development-vagrant.mdx index fd856081027c..30fdb8684c7a 100644 --- a/src/content/guides/development-vagrant.mdx +++ b/src/content/guides/development-vagrant.mdx @@ -21,10 +21,10 @@ Vagrant.configure("2") do |config| end ``` -Next, install `webpack`, `webpack-cli`, `@webpack-cli/serve`, and `webpack-dev-server` in your project; +Next, install `webpack`, `webpack-cli`, and `webpack-dev-server` in your project; ```bash -npm install --save-dev webpack webpack-cli @webpack-cli/serve webpack-dev-server +npm install --save-dev webpack webpack-cli webpack-dev-server ``` Make sure to have a `webpack.config.js` file. If you haven't already, use this as a minimal example to get started: @@ -42,13 +42,13 @@ export default { }; ``` -And create an `index.html` file. The script tag should point to your bundle. If `output.filename` is not specified in the config, this will be `bundle.js`. +And create an `index.html` file. The script tag should point to your bundle. If `output.filename` is not specified in the config, this will be `main.js` (`[name].js` for the default `main` entry). ```html - +

Hey!

diff --git a/src/content/guides/ecma-script-modules.mdx b/src/content/guides/ecma-script-modules.mdx index b6bf736111b5..892b205bb559 100644 --- a/src/content/guides/ecma-script-modules.mdx +++ b/src/content/guides/ecma-script-modules.mdx @@ -172,28 +172,30 @@ export default { CommonJS syntax is not available in ESM: `require`, `module`, `exports`, `__filename`, `__dirname`. -When importing from a CommonJS module inside ESM, only the `default` export -is available (the entire `module.exports` object): +When webpack bundles a CommonJS module imported from ESM, both the `default` +import (the entire `module.exports` object) and named imports (its properties) work: ```js // esm-consumer.js (ESM) import cjs from "./cjs-module.js"; -// named imports from CJS don't work -import { foo } from "./cjs-module.js"; // undefined +import { foo } from "./cjs-module.js"; // cjs-module.js (CommonJS) module.exports = { foo: 1, bar: 2 }; -console.log(cjs.foo); // works - cjs is the whole exports object +console.log(cjs.foo); // 1 - cjs is the whole exports object +console.log(foo); // 1 - named imports read properties of module.exports ``` -This strict behavior applies when webpack treats the **imported** module as CommonJS. +This interop applies when webpack treats the **imported** module as CommonJS. If that module itself uses ESM `export` syntax, webpack will auto-detect it as ESM -and named imports will work normally. This commonly affects projects that mix `.js` files +and use its exports directly. This commonly affects projects that mix `.js` files files in a project that has `"type": "module"` set - webpack may treat some files as ESM while third-party packages in `node_modules` remain CommonJS. -T> To get named exports from CommonJS modules, consider migrating to ESM +T> This is webpack's bundling behavior. When Node.js itself loads a CommonJS module from ESM, +T> named imports only work if Node.js can detect them statically; otherwise only the `default` +T> import is available - consider migrating to ESM T> or using [`@babel/plugin-transform-modules-commonjs`](https://babeljs.io/docs/babel-plugin-transform-modules-commonjs). ## Common Migration Errors diff --git a/src/content/guides/hot-module-replacement.mdx b/src/content/guides/hot-module-replacement.mdx index 64cf42c8fa08..80405f4259fa 100644 --- a/src/content/guides/hot-module-replacement.mdx +++ b/src/content/guides/hot-module-replacement.mdx @@ -123,7 +123,7 @@ you can also provide manual entry points for HMR: }; ``` -T> You can use the CLI to modify the [webpack-dev-server](https://github.com/webpack/webpack-dev-server) configuration with the following command: `webpack serve --hot-only`. +T> You can use the CLI to modify the [webpack-dev-server](https://github.com/webpack/webpack-dev-server) configuration with the following command: `webpack serve --hot only`. Now let's update the `index.js` file so that when a change inside `print.js` is detected we tell webpack to accept the updated module. diff --git a/src/content/guides/lazy-loading.mdx b/src/content/guides/lazy-loading.mdx index 015fe67ee24a..88e888118f37 100644 --- a/src/content/guides/lazy-loading.mdx +++ b/src/content/guides/lazy-loading.mdx @@ -243,7 +243,8 @@ export const greeting = "Bonjour"; ```text const language = navigator.language.split("-")[0]; // "en", "fr", etc. -const locale = import.defer("./locales/" + language + ".js"); +// Resolves to a deferred namespace; nothing is evaluated yet. +const locale = await import.defer("./locales/" + language + ".js"); document.getElementById("btn").addEventListener("click", () => { // The locale module is evaluated here, on first property access. diff --git a/src/content/guides/native-css.mdx b/src/content/guides/native-css.mdx index ac880f168295..170a04394eae 100644 --- a/src/content/guides/native-css.mdx +++ b/src/content/guides/native-css.mdx @@ -72,12 +72,12 @@ Webpack processes the CSS and includes it in the build output. Native CSS introduces four [`Rule.type`](/configuration/module/#ruletype) values. Knowing which one applies is the key to migrating, because each maps to a different `css-loader` `modules.mode`: -| Type | Scoping | `css-loader` equivalent | -| ------------ | ------------------------------------------------------------------------------- | ------------------------ | -| `css` | Global, no CSS Modules parsing | `modules: false` | -| `css/global` | Global selectors, but `:local()` is honored | `modules.mode: 'global'` | -| `css/module` | Local by default, `:global()` escapes to global | `modules.mode: 'local'` | -| `css/auto` | Picks `css/module` for `*.module.css` / `*.modules.css`, otherwise `css/global` | `modules.auto: true` | +| Type | Scoping | `css-loader` equivalent | +| ------------ | --------------------------------------------------------------------------------------------------------------- | ------------------------ | +| `css` | Global, no CSS Modules parsing | `modules: false` | +| `css/global` | Global selectors, but `:local()` is honored | `modules.mode: 'global'` | +| `css/module` | Local by default, `:global()` escapes to global | `modules.mode: 'local'` | +| `css/auto` | Picks `css/module` for `*.module.css` / `*.modules.css`, otherwise plain `css` (global, no CSS Modules parsing) | `modules.auto: true` | The default rule webpack adds for `/\.css$/i` is `css/auto`, so `*.module.css` files become CSS Modules and everything else stays global — matching the most common `css-loader` configuration out of the box. @@ -220,7 +220,7 @@ Native CSS resolves `@custom-media` and `@custom-selector` at build time, so the } ``` -Resolution is file-local — a definition applies to the file that declares it (and to what that file `@import`s) rather than to the whole project. Both are on by default and can be switched off individually with [`module.parser.css.customMedia`](/configuration/module/#moduleparsercsscustommedia) and [`module.parser.css.customSelectors`](/configuration/module/#moduleparsercsscustomselectors), which is what you want if a PostCSS plugin in your chain already handles them. +Resolution is file-local — a definition applies only to the file that declares it, not to the files it `@import`s nor to the whole project. Both are on by default and can be switched off individually with [`module.parser.css.customMedia`](/configuration/module/#moduleparsercsscustommedia) and [`module.parser.css.customSelectors`](/configuration/module/#moduleparsercsscustomselectors), which is what you want if a PostCSS plugin in your chain already handles them. ## Minification @@ -435,13 +435,13 @@ Native CSS extracts stylesheets and adds content hashes to them by default (`exp Map the remaining plugin options: -| `mini-css-extract-plugin` | Native equivalent | -| ------------------------- | ------------------------------------------------------------------------------- | -| `filename` | [`output.cssFilename`](/configuration/output/#outputcssfilename) | -| `chunkFilename` | [`output.cssChunkFilename`](/configuration/output/#outputcsschunkfilename) | -| loader `publicPath` | [`output.publicPath`](/configuration/output/#outputpublicpath) | -| loader `esModule` | generator [`esModule`](/configuration/module/#modulegenerator) (default `true`) | -| `ignoreOrder` | n/a — native CSS does not emit order-conflict warnings | +| `mini-css-extract-plugin` | Native equivalent | +| ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `filename` | [`output.cssFilename`](/configuration/output/#outputcssfilename) | +| `chunkFilename` | [`output.cssChunkFilename`](/configuration/output/#outputcsschunkfilename) | +| loader `publicPath` | [`output.publicPath`](/configuration/output/#outputpublicpath) | +| loader `esModule` | generator [`esModule`](/configuration/module/#modulegenerator) (default `true`) | +| `ignoreOrder` | n/a — the order-conflict warning cannot be silenced per option; use [`ignoreWarnings`](/configuration/other-options/#ignorewarnings), or `CssModulesPlugin.getCompilationHooks(compilation).orderModules` to define the order yourself | **webpack.config.js** diff --git a/src/content/guides/native-html.mdx b/src/content/guides/native-html.mdx index 6ab588ba6987..f57e1a03717e 100644 --- a/src/content/guides/native-html.mdx +++ b/src/content/guides/native-html.mdx @@ -88,7 +88,7 @@ export default { This is the HTML-first model Vite and Parcel use: the page is the source of truth about which scripts and styles it needs, so there is no second list of entry points to keep in sync. -T> When `experiments.html` is enabled, `.html` is added to the default [`resolve.extensions`](/configuration/resolve/#resolveextensions) ahead of the JavaScript extensions, so `entry: './src'` resolves `./src/index.html` even when `./src/index.js` exists. +T> When `experiments.html` is set to `true` explicitly, `.html` is added to the default [`resolve.extensions`](/configuration/resolve/#resolveextensions) ahead of the JavaScript extensions, so `entry: './src'` resolves `./src/index.html` even when `./src/index.js` exists. With the `'auto'` default, `.html` is only a fallback after `.js`. ### 2. A generated page for a JavaScript entry @@ -531,7 +531,7 @@ Inline `