diff --git a/src/content/blog/2026-06-25-webpack-5-108.mdx b/src/content/blog/2026-06-25-webpack-5-108.mdx index 47306006c8b6..cc3fd4a309c1 100644 --- a/src/content/blog/2026-06-25-webpack-5-108.mdx +++ b/src/content/blog/2026-06-25-webpack-5-108.mdx @@ -54,7 +54,7 @@ module.exports = { [`target: "universal"`](/configuration/target/#universal) combines the `web`, `web worker`, `node`, `electron`, and `nwjs` platforms into one target and leaves each platform flag _neutral_ instead of locking the bundle to a single environment. Rather than compiling separate web and node bundles, you ship one bundle that figures out its surroundings at runtime and uses whatever the current platform provides. -A bundle that has to load equally well in a browser and in Node needs a portable module format, so universal builds always output ECMAScript modules: [`experiments.outputModule`](/configuration/experiments/#experimentsoutputmodule) defaults to `true`, synchronous `require` is turned off, and Node's built-in modules stay available (resolved at runtime through ESM). [`output.globalObject`](/configuration/output/#outputglobalobject) also defaults to `globalThis` so runtime code has one global to reach for on every platform. +A bundle that has to load equally well in a browser and in Node needs a portable module format, so universal builds always output ECMAScript modules: [`output.module`](/configuration/output/#outputmodule) defaults to `true`, synchronous `require` is turned off, and Node's built-in modules stay available (resolved at runtime through ESM). [`output.globalObject`](/configuration/output/#outputglobalobject) also defaults to `globalThis` so runtime code has one global to reach for on every platform. To make a single bundle behave correctly everywhere, several pieces were made platform-aware and now branch on feature detection at runtime instead of being fixed at build time: diff --git a/src/content/configuration/experiments.mdx b/src/content/configuration/experiments.mdx index 21fd57198950..e14ad9fbe8fc 100644 --- a/src/content/configuration/experiments.mdx +++ b/src/content/configuration/experiments.mdx @@ -29,10 +29,10 @@ Available options: - [`futureDefaults`](#experimentsfuturedefaults) - [`html`](#experimentshtml) - [`lazyCompilation`](#experimentslazycompilation) -- [`outputModule`](#experimentsoutputmodule) - [`typescript`](#experimentstypescript) - [`sourceImport`](#experimentssourceimport) - `syncWebAssembly`: Support the old WebAssembly like in webpack 4. +- `outputModule`: Output ECMAScript module syntax wherever possible, removed since `5.111.0` — set [`output.module`](/configuration/output/#outputmodule) to `true` instead, it no longer needs an experiment. - `layers`: Enable module and chunk layers, removed and works without additional options since `5.102.0`. - `topLevelAwait`: Transforms a module into an `async` module when an `await` is used at the top level. Starting from webpack version `5.83.0` (however, in versions prior to that, you can enable it by setting `experiments.topLevelAwait` to `true`), this feature is enabled by default, removed and works without additional options since `5.102.0`. @@ -45,7 +45,6 @@ export default { asyncWebAssembly: true, buildHttp: true, lazyCompilation: true, - outputModule: true, sourceImport: true, syncWebAssembly: true, topLevelAwait: true, @@ -606,20 +605,6 @@ Compile entrypoints and dynamic `import`s only when they are in use. It can be u }; ``` -### experiments.outputModule - -`boolean` - -Once enabled, webpack will output ECMAScript module syntax whenever possible. For instance, `import()` to load chunks, ESM exports to expose chunk data, among others. - -```js -export default { - experiments: { - outputModule: true, - }, -}; -``` - ### experiments.typescript diff --git a/src/content/configuration/externals.mdx b/src/content/configuration/externals.mdx index b7318bbf0a6c..b75118c97059 100644 --- a/src/content/configuration/externals.mdx +++ b/src/content/configuration/externals.mdx @@ -546,7 +546,7 @@ jq(".my-element").animate(/* ... */); Specify the default type of externals as `'module'`. Webpack will generate code like `import * as X from '...'` for externals used in a module. -Make sure to enable [`experiments.outputModule`](/configuration/experiments/#experimentsoutputmodule) first, otherwise webpack will throw errors. +Make sure to enable [`output.module`](/configuration/output/#outputmodule) first, otherwise webpack will throw errors. #### Example @@ -560,8 +560,8 @@ jq(".my-element").animate(/* ... */); ```js export default { - experiments: { - outputModule: true, + output: { + module: true, }, externalsType: "module", externals: { @@ -670,7 +670,7 @@ const src = await import.source("external-mod"); Specify the default type of externals as `'module-import'`. This combines [`'module'`](#externalstypemodule) and [`'import'`](#externalstypeimport). Webpack will automatically detect the type of import syntax, setting it to `'module'` for static imports and `'import'` for dynamic imports. -Ensure to enable [`experiments.outputModule`](/configuration/experiments/#experimentsoutputmodule) first if static imports exist, otherwise, webpack will throw errors. +Ensure to enable [`output.module`](/configuration/output/#outputmodule) first if static imports exist, otherwise, webpack will throw errors. #### Example @@ -752,8 +752,8 @@ jq(".my-element").animate(/* ... */); ```js module.export = { - experiments: { - outputModule: true, + output: { + module: true, }, externalsType: "node-commonjs", externals: { @@ -790,7 +790,7 @@ You can use `node-commonjs` to ensure that the prototype chain is preserved: const { builtinModules } = require("node:module"); export default { - experiments: { outputModule: true }, + output: { module: true }, externalsType: "node-commonjs", externals: ({ request }, callback) => { if (request.startsWith("node:") || builtinModules.includes(request)) { diff --git a/src/content/configuration/output.mdx b/src/content/configuration/output.mdx index 651fa4bd429b..8e7231c138a3 100644 --- a/src/content/configuration/output.mdx +++ b/src/content/configuration/output.mdx @@ -1812,10 +1812,8 @@ These options will result in a bundle that comes with a complete header to ensur ```js export default { // … - experiments: { - outputModule: true, - }, output: { + module: true, library: { // do not specify a `name` here type: "module", @@ -1824,9 +1822,7 @@ export default { }; ``` -Output ES Module. - -However this feature is still experimental and not fully supported yet, so make sure to enable [experiments.outputModule](/configuration/experiments/) beforehand. In addition, you can track the development progress in [this thread](https://github.com/webpack/webpack/issues/2933#issuecomment-774253975). +Output ES Module. You can track the remaining development progress in [this thread](https://github.com/webpack/webpack/issues/2933#issuecomment-774253975). ##### type: 'modern-module' @@ -1835,10 +1831,8 @@ However this feature is still experimental and not fully supported yet, so make ```js export default { // … - experiments: { - outputModule: true, - }, output: { + module: true, library: { // do not specify a `name` here type: "modern-module", @@ -1849,8 +1843,6 @@ export default { This configuration generates tree-shakable output for ES Modules. -However this feature is still experimental and not fully supported yet, so make sure to enable [experiments.outputModule](/configuration/experiments/) beforehand. - ##### type: 'commonjs2' ```js @@ -2452,7 +2444,7 @@ These options will result in a bundle that comes with a complete header to ensur W> Prefer to use [`output.library.type: 'module'`](#type-module). -Output ES Module. Make sure to enable [experiments.outputModule](/configuration/experiments/) beforehand. +Output ES Module. Make sure to enable [`output.module`](#outputmodule) beforehand. Note that this feature is not fully supported yet, please track the progress in [this thread](https://github.com/webpack/webpack/issues/2933#issuecomment-774253975). @@ -2677,7 +2669,7 @@ The dependencies for your library will be defined by the [`externals`](/configur `boolean = false` -Output JavaScript files as module type. Disabled by default as it's an experimental feature. +Output JavaScript files as module type. It defaults to `true` for the [`universal`](/configuration/target/#universal), [`deno`](/configuration/target/#deno) and [`bun`](/configuration/target/#bun) targets, which only run ECMAScript modules, and to `false` everywhere else. When enabled, webpack will set [`output.iife`](#outputiife) to `false`, [`output.scriptType`](#outputscripttype) to `'module'` and `minimizerOptions.module` to `true` internally. @@ -2686,16 +2678,15 @@ If you're using webpack to compile a library to be consumed by others, make sure ```js export default { // ... - experiments: { - outputModule: true, - }, output: { module: true, }, }; ``` -W> `output.module` is an experimental feature and can only be enabled by setting [`experiments.outputModule`](/configuration/experiments/#experiments) to `true`. [One of the known problems](https://github.com/webpack/webpack/issues/11277#issuecomment-992565287) is that such a library can't be consumed by webpack4-based (and possibly other too) applications. +T> Until webpack `5.111.0` this option also required [`experiments.outputModule`](/configuration/experiments/); that experiment has been removed and `output.module` now works on its own. + +W> [One of the known problems](https://github.com/webpack/webpack/issues/11277#issuecomment-992565287) is that such a library can't be consumed by webpack4-based (and possibly other too) applications. ## output.path diff --git a/src/content/configuration/performance.mdx b/src/content/configuration/performance.mdx index 08021fecd8c3..b380aa0d83d9 100644 --- a/src/content/configuration/performance.mdx +++ b/src/content/configuration/performance.mdx @@ -109,7 +109,6 @@ What each reason means, and what lifts it: ```js export default { // ... - experiments: { outputModule: true }, output: { module: true }, performance: { hints: "warning", diff --git a/src/content/configuration/target.mdx b/src/content/configuration/target.mdx index b252e3b2e5ce..a3d3045eb6eb 100644 --- a/src/content/configuration/target.mdx +++ b/src/content/configuration/target.mdx @@ -80,7 +80,7 @@ Supported browserslist values: -A single preset that combines the `web`, `web worker`, `node`, `electron` and `nwjs` platforms, leaving each platform flag neutral so the bundle adapts at runtime instead of being locked to one environment. It is a convenient replacement for hand-writing `target: ["web", "node"]`, and it always outputs ECMAScript modules. [`experiments.outputModule`](/configuration/experiments/#experimentsoutputmodule) defaults to `true` for this target. +A single preset that combines the `web`, `web worker`, `node`, `electron` and `nwjs` platforms, leaving each platform flag neutral so the bundle adapts at runtime instead of being locked to one environment. It is a convenient replacement for hand-writing `target: ["web", "node"]`, and it always outputs ECMAScript modules. [`output.module`](/configuration/output/#outputmodule) defaults to `true` for this target. **webpack.config.js** @@ -101,7 +101,7 @@ Notes for universal builds: -Compile for [Bun](https://bun.sh/). The bundle is emitted as ECMAScript modules ([`experiments.outputModule`](/configuration/experiments/#experimentsoutputmodule) defaults to `true`), and Bun's own `bun:*` modules together with the Node.js built-in modules Bun provides are externalized instead of being bundled. +Compile for [Bun](https://bun.sh/). The bundle is emitted as ECMAScript modules ([`output.module`](/configuration/output/#outputmodule) defaults to `true`), and Bun's own `bun:*` modules together with the Node.js built-in modules Bun provides are externalized instead of being bundled. **webpack.config.js** @@ -116,7 +116,7 @@ export default { -Compile for [Deno](https://deno.com/). The bundle is emitted as ECMAScript modules ([`experiments.outputModule`](/configuration/experiments/#experimentsoutputmodule) defaults to `true`). Node.js built-ins are resolved through the `node:` specifier Deno requires, and Deno's own import protocols (`npm:`, `jsr:`, `node:` and `http(s)://` URLs) are kept external so the runtime loads them. A version may be specified, for example `deno2` or `deno1.40`. +Compile for [Deno](https://deno.com/). The bundle is emitted as ECMAScript modules ([`output.module`](/configuration/output/#outputmodule) defaults to `true`). Node.js built-ins are resolved through the `node:` specifier Deno requires, and Deno's own import protocols (`npm:`, `jsr:`, `node:` and `http(s)://` URLs) are kept external so the runtime loads them. A version may be specified, for example `deno2` or `deno1.40`. **webpack.config.js** diff --git a/src/content/guides/modern-web-platform.mdx b/src/content/guides/modern-web-platform.mdx index c2532d0a0388..8e8bddc88e87 100644 --- a/src/content/guides/modern-web-platform.mdx +++ b/src/content/guides/modern-web-platform.mdx @@ -70,7 +70,7 @@ Splitting alone does not change **browser** rules: the tag name must still be re ### Approach -Enable [ES module output](/configuration/output/#outputmodule) (`experiments.outputModule` and `output.module`), set [`externalsType: "module"`](/configuration/externals/#externalstypemodule) for static imports, and list each bare specifier in `externals` with the same string the browser will resolve via the import map. +Enable [ES module output](/configuration/output/#outputmodule) (`output.module`), set [`externalsType: "module"`](/configuration/externals/#externalstypemodule) for static imports, and list each bare specifier in `externals` with the same string the browser will resolve via the import map. **webpack.config.js** @@ -83,9 +83,6 @@ const __dirname = path.dirname(__filename); export default { mode: "production", - experiments: { - outputModule: true, - }, entry: "./src/index.js", externalsType: "module", externals: { @@ -131,7 +128,7 @@ The key `"lodash-es"` must match both the **`externals` key** and the **specifie ``` -W> [`experiments.outputModule`](/configuration/experiments/#experimentsoutputmodule) and [`output.module`](/configuration/output/#outputmodule) are still experimental. Check the latest [webpack release notes](https://github.com/webpack/webpack/releases) before relying on them in production. +W> Check the latest [webpack release notes](https://github.com/webpack/webpack/releases) for the current state of [`output.module`](/configuration/output/#outputmodule) before relying on it in production. ### Limitations and future work diff --git a/src/content/guides/native-html.mdx b/src/content/guides/native-html.mdx index 3cd3930b1ef6..9c39cf61dc42 100644 --- a/src/content/guides/native-html.mdx +++ b/src/content/guides/native-html.mdx @@ -1093,7 +1093,7 @@ A `UrlHintRule` — used by `output.resourceHints.urlHints` and by every parser' ```js export default { - experiments: { html: true, outputModule: true }, + experiments: { html: true }, output: { module: true, resourceHints: {