Skip to content

Commit 0c5c155

Browse files
committed
feat: add built-in HTML minimizers from html-minimizer-webpack-plugin
Move the HTML minifier implementations from `html-minimizer-webpack-plugin` into this plugin so HTML assets can be minified via the standard `TerserPlugin` interface. Adds four new static helpers: - `TerserPlugin.htmlMinifierTerser` (uses `html-minifier-terser`) - `TerserPlugin.swcMinifyHtml` (uses `@swc/html` for full documents) - `TerserPlugin.swcMinifyHtmlFragment` (uses `@swc/html` for fragments) - `TerserPlugin.minifyHtmlNode` (uses `@minify-html/node`) The HTML packages are declared as optional peer dependencies — install only the one you actually use. Documentation in the README now includes a dedicated HTML section with usage examples for each minimizer.
1 parent e6fc053 commit 0c5c155

9 files changed

Lines changed: 1164 additions & 21 deletions

File tree

.cspell.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,10 @@
3737
"toplevel",
3838
"commitlint",
3939
"tapable",
40-
"nocheck"
40+
"nocheck",
41+
"dont",
42+
"doctype",
43+
"wilsonzlin"
4144
],
4245
"ignorePaths": [
4346
"CHANGELOG.md",

README.md

Lines changed: 184 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,13 @@
1313

1414
# terser-webpack-plugin
1515

16-
This plugin uses [terser](https://github.com/terser/terser) to minify/minimize your JavaScript.
16+
This plugin uses [terser](https://github.com/terser/terser) to minify/minimize your JavaScript by default, and can also minify other asset types — JSON and HTML — via built-in minimizers.
17+
18+
For HTML it can use 3 tools:
19+
20+
- [`html-minifier-terser`](https://github.com/terser/html-minifier-terser) — JavaScript-based HTML minifier (the default for HTML).
21+
- [`@swc/html`](https://github.com/swc-project/swc) — very fast Rust-based platform for the Web.
22+
- [`@minify-html/node`](https://github.com/wilsonzlin/minify-html) — a Rust HTML minifier, optimised for speed.
1723

1824
## Getting Started
1925

@@ -892,6 +898,155 @@ module.exports = {
892898
};
893899
```
894900

901+
### HTML
902+
903+
The plugin can minify HTML assets too. Pick one of the bundled HTML
904+
minimizers and set `test` to match your HTML files.
905+
906+
Available HTML minimizers:
907+
908+
- `TerserPlugin.htmlMinifierTerser` — uses [`html-minifier-terser`](https://github.com/terser/html-minifier-terser).
909+
- `TerserPlugin.swcMinifyHtml` — uses [`@swc/html`](https://github.com/swc-project/swc) for full HTML documents (with doctype and `<html>`/`<head>`/`<body>` tags).
910+
- `TerserPlugin.swcMinifyHtmlFragment` — uses [`@swc/html`](https://github.com/swc-project/swc) for HTML fragments (e.g. content inside `<template></template>` or partial HTML strings).
911+
- `TerserPlugin.minifyHtmlNode` — uses [`@minify-html/node`](https://github.com/wilsonzlin/minify-html).
912+
913+
The HTML minimizers are optional peer dependencies — install only the one
914+
you actually use:
915+
916+
```console
917+
npm install --save-dev html-minifier-terser
918+
# or
919+
npm install --save-dev @swc/html
920+
# or
921+
npm install --save-dev @minify-html/node
922+
```
923+
924+
> **Note**
925+
>
926+
> HTML assets typically come from plugins like
927+
> [`copy-webpack-plugin`](https://github.com/webpack-contrib/copy-webpack-plugin),
928+
> [`html-webpack-plugin`](https://github.com/jantimon/html-webpack-plugin),
929+
> or webpack's [asset modules](https://webpack.js.org/guides/asset-modules/).
930+
931+
> **Note**
932+
>
933+
> Whitespace handling differs between tools (defaults):
934+
>
935+
> - `@swc/html` — removes/collapses whitespace only in safe places (around `html`/`body`, inside `<head>`, between `<meta>`/`<script>`/`<link>` etc.).
936+
> - `html-minifier-terser` — always collapses multiple whitespaces to a single space (never removes entirely); configurable via [its options](https://github.com/terser/html-minifier-terser#options-quick-reference).
937+
> - `@minify-html/node` — see [its whitespace docs](https://github.com/wilsonzlin/minify-html#whitespace).
938+
939+
#### `html-minifier-terser`
940+
941+
[`html-minifier-terser`](https://github.com/terser/html-minifier-terser) is a JavaScript-based HTML minifier with no native dependency. It's the default HTML minimizer.
942+
943+
**webpack.config.js**
944+
945+
```js
946+
const TerserPlugin = require("terser-webpack-plugin");
947+
948+
module.exports = {
949+
optimization: {
950+
minimize: true,
951+
minimizer: [
952+
// Keeps the default Terser plugin for JS files
953+
"...",
954+
new TerserPlugin({
955+
test: /\.html(\?.*)?$/i,
956+
minify: TerserPlugin.htmlMinifierTerser,
957+
// Options - https://github.com/terser/html-minifier-terser#options-quick-reference
958+
minimizerOptions: {
959+
collapseWhitespace: true,
960+
removeComments: true,
961+
},
962+
}),
963+
],
964+
},
965+
};
966+
```
967+
968+
#### `@swc/html` — HTML documents
969+
970+
Use `swcMinifyHtml` for complete HTML documents (i.e. with a doctype and `<html>`/`<head>`/`<body>` tags).
971+
972+
**webpack.config.js**
973+
974+
```js
975+
const TerserPlugin = require("terser-webpack-plugin");
976+
977+
module.exports = {
978+
optimization: {
979+
minimize: true,
980+
minimizer: [
981+
"...",
982+
new TerserPlugin({
983+
test: /\.html(\?.*)?$/i,
984+
minify: TerserPlugin.swcMinifyHtml,
985+
// Options - https://github.com/swc-project/bindings/blob/main/packages/html/index.ts
986+
minimizerOptions: {},
987+
}),
988+
],
989+
},
990+
};
991+
```
992+
993+
#### `@swc/html` — HTML fragments
994+
995+
Use `swcMinifyHtmlFragment` for partial HTML — for example, content of `<template></template>` tags or HTML strings that get injected into another document.
996+
997+
**webpack.config.js**
998+
999+
```js
1000+
const TerserPlugin = require("terser-webpack-plugin");
1001+
1002+
module.exports = {
1003+
optimization: {
1004+
minimize: true,
1005+
minimizer: [
1006+
"...",
1007+
new TerserPlugin({
1008+
test: /\.template\.html$/i,
1009+
minify: TerserPlugin.swcMinifyHtmlFragment,
1010+
// Options - https://github.com/swc-project/bindings/blob/main/packages/html/index.ts
1011+
minimizerOptions: {},
1012+
}),
1013+
],
1014+
},
1015+
};
1016+
```
1017+
1018+
> **Note**
1019+
>
1020+
> The difference between `swcMinifyHtml` and `swcMinifyHtmlFragment` is the
1021+
> error reporting — invalid or broken syntax is reported at build time.
1022+
1023+
#### `@minify-html/node`
1024+
1025+
[`@minify-html/node`](https://github.com/wilsonzlin/minify-html) is a Rust HTML minifier.
1026+
1027+
**webpack.config.js**
1028+
1029+
```js
1030+
const TerserPlugin = require("terser-webpack-plugin");
1031+
1032+
module.exports = {
1033+
optimization: {
1034+
minimize: true,
1035+
minimizer: [
1036+
"...",
1037+
new TerserPlugin({
1038+
test: /\.html(\?.*)?$/i,
1039+
minify: TerserPlugin.minifyHtmlNode,
1040+
// Options - https://github.com/wilsonzlin/minify-html#minification
1041+
minimizerOptions: {},
1042+
}),
1043+
],
1044+
},
1045+
};
1046+
```
1047+
1048+
You can also stack multiple `TerserPlugin` instances to compress different files with different `minify` functions in the same build (e.g. JS with `terserMinify`, HTML with `htmlMinifierTerser`, JSON with `jsonMinify`).
1049+
8951050
### Custom Minify Function
8961051

8971052
Override the default minify function - use `uglify-js` for minification.
@@ -947,7 +1102,12 @@ With built-in minify functions:
9471102

9481103
```ts
9491104
import { type JsMinifyOptions as SwcOptions } from "@swc/core";
1105+
import {
1106+
type FragmentOptions as SwcHtmlFragmentOptions,
1107+
type Options as SwcHtmlOptions,
1108+
} from "@swc/html";
9501109
import { type TransformOptions as EsbuildOptions } from "esbuild";
1110+
import { type Options as HtmlMinifierTerserOptions } from "html-minifier-terser";
9511111
import { type MinifyOptions as TerserOptions } from "terser";
9521112
import { type MinifyOptions as UglifyJSOptions } from "uglify-js";
9531113

@@ -981,6 +1141,29 @@ module.exports = {
9811141
// `terser` options
9821142
},
9831143
}),
1144+
1145+
// HTML minimizers
1146+
new TerserPlugin<HtmlMinifierTerserOptions>({
1147+
test: /\.html(\?.*)?$/i,
1148+
minify: TerserPlugin.htmlMinifierTerser,
1149+
minimizerOptions: {
1150+
// `html-minifier-terser` options
1151+
},
1152+
}),
1153+
new TerserPlugin<SwcHtmlOptions>({
1154+
test: /\.html(\?.*)?$/i,
1155+
minify: TerserPlugin.swcMinifyHtml,
1156+
minimizerOptions: {
1157+
// `@swc/html` options
1158+
},
1159+
}),
1160+
new TerserPlugin<SwcHtmlFragmentOptions>({
1161+
test: /\.template\.html$/i,
1162+
minify: TerserPlugin.swcMinifyHtmlFragment,
1163+
minimizerOptions: {
1164+
// `@swc/html` fragment options
1165+
},
1166+
}),
9841167
],
9851168
},
9861169
};

0 commit comments

Comments
 (0)