Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions src/content/api/module-methods.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,22 @@ We support `webpackIgnore` in the following cases:

T> For other CSS scenarios, [`css-loader` fully supports `webpackIgnore`](/loaders/css-loader/#disable-url-resolving-using-the--webpackignore-true--comment), allowing more flexibility if needed.

**HTML Usage**

<Badge text="5.107.0+" />

When [`experiments.html`](/configuration/experiments/#experimentshtml) is enabled, `webpackIgnore` can be placed as an HTML comment immediately before a tag to skip URL resolution for that tag's `src`, `href`, `srcset`, and similar attributes. The tag is left untouched in the emitted HTML. This mirrors the behavior provided by `html-loader`.

```html
<!-- webpackIgnore: true -->
<img src="https://cdn.example.com/logo.png" />

<!-- webpackIgnore: true -->
<script src="/legacy/external.js"></script>
```

The magic-comment value is parsed with the same context used by the JS and CSS parsers; non-boolean values emit an `UnsupportedFeatureWarning`.

##### webpackChunkName

A name for the new chunk. Since webpack 2.6.0, the placeholders `[index]` and `[request]` are supported within the given string to an incremented number or the actual resolved filename respectively. Adding this comment will cause our separate chunk to be named [my-chunk-name].js instead of [id].js.
Expand Down
113 changes: 113 additions & 0 deletions src/content/configuration/experiments.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Available options:
- [`css`](#experimentscss)
- [`deferImport`](#experimentsdeferimport)
- [`futureDefaults`](#experimentsfuturedefaults)
- [`html`](#experimentshtml)
- [`lazyCompilation`](#experimentslazycompilation)
- [`outputModule`](#experimentsoutputmodule)
- `syncWebAssembly`: Support the old WebAssembly like in webpack 4.
Expand Down Expand Up @@ -310,6 +311,118 @@ export default {
};
```

### experiments.html

<Badge text="5.107.0+" />

Enable native HTML module support. Importing a `.html` file from JavaScript runs its tag references through the normal webpack pipeline, replacing the role `html-loader` has played for years. The flag registers the `html` module type on `NormalModuleFactory` and unlocks the HTML behaviors described below.

- Type: `boolean`
- Default: `false`

**webpack.config.js**

```js
export default {
// ...
experiments: {
html: true,
},
};
```

Then import the HTML file from JavaScript. The default export is the processed HTML as a string, with all asset references resolved through webpack:

```js
// src/index.js
import page from "./page.html";

document.documentElement.innerHTML = page;
```

W> **This feature is experimental and partial.** Webpack 5.107 only implements the `html-loader` side: importing an HTML file from JS runs its tag references through the webpack pipeline. **HTML entry points** (using a `.html` file directly as `entry`, the `html-webpack-plugin` part) are **not supported yet** and are planned for the next minor release. The full story is tracked in issue [#536](https://github.com/webpack/webpack/issues/536).

#### Inline `<style>` tags

Inline `<style>` blocks inside an HTML module are routed through webpack's CSS pipeline as virtual CSS modules with `exportType: "text"`. `url()` and `@import` references are resolved relative to the HTML file, and the processed CSS text is written back into the original `<style>` tag in the emitted HTML string.

```html
<!-- src/page.html -->
<!doctype html>
<html>
<head>
<style>
@import "./reset.css";

body {
background: url("./bg.png");
}
</style>
</head>
<body>
...
</body>
</html>
```

`<style type="text/css">` and `<style>` with no `type` attribute are processed. Anything with a non-CSS `type` is passed through unchanged.

#### Inline `<script>` tags

Inline `<script>` bodies are routed through the same entry pipeline used for [`<script src>`](#script-src-and-link-relmodulepreload). Each `<script>` body becomes its own webpack entry: classic inline scripts are bundled as CommonJS, and `<script type="module">` bodies are bundled as ESM. The tag in the emitted HTML is rewritten to `<script src="…">` pointing at the generated chunk, with the body cleared.

```html
<!-- src/page.html -->
<!doctype html>
<html>
<body>
<script type="module">
import { greet } from "./lib.js";
greet("world");
</script>

<script>
console.log("classic inline script");
</script>
</body>
</html>
```

The same behaviors that apply to external `<script src>` apply here too:

- When [`output.module`](/configuration/output/#outputmodule) is enabled, classic inline `<script>` tags are auto-upgraded to `type="module"`, matching the auto-upgrade for `<script src>`.
- `webpackIgnore` works on inline `<script>` tags as well, leaving the original body untouched.
- Non-JS `type` values such as `application/ld+json` and `importmap` pass through unchanged.

#### `<script src>` and `<link rel="modulepreload">`

`<script src>` and `<link rel="modulepreload">` references inside an HTML module become real webpack entries. The emitted chunk URL is rewritten back into the HTML string, so hashed filenames work the same way they do for JavaScript imports.

```html
<!-- src/page.html -->
<!doctype html>
<html>
<head>
<link rel="modulepreload" href="./preloaded.js" />
</head>
<body>
<script src="./entry.js"></script>
<script src="./second.js"></script>
</body>
</html>
```

A few behaviors to keep in mind:

- Multiple `<script src>` tags on the same page share a single runtime. Within each group (classic or `type="module"`), the leader holds the runtime and the rest declare `dependOn` on it.
- `<link rel="modulepreload">` entries stay independent and are never imported by sibling scripts, preserving "preload without execute" semantics.
- When [`output.module`](/configuration/output/#outputmodule) is enabled, classic `<script src>` tags are auto-upgraded to `<script type="module" src>` so the emitted ES-module chunks load in the correct mode.
- Non-JS script types (`application/ld+json`, `importmap`, …) and data URIs flow through unchanged and are not bundled as JS.

#### `webpackIgnore` magic comment

Placing an HTML `<!-- webpackIgnore: true -->` comment immediately before a tag tells webpack to skip URL resolution for that tag's `src`, `href`, `srcset`, and similar attributes. See the full description under [magic comments](/api/module-methods/#webpackignore).

### experiments.lazyCompilation

Compile entrypoints and dynamic `import`s only when they are in use. It can be used for either Web or Node.js.
Expand Down
Loading