Skip to content

Commit 9ddd343

Browse files
feat: add built-in HTML minimizers from html-minimizer-webpack-plugin (#668)
1 parent e6fc053 commit 9ddd343

14 files changed

Lines changed: 1401 additions & 21 deletions

.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: 202 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,31 @@
1313

1414
# terser-webpack-plugin
1515

16-
This plugin uses [terser](https://github.com/terser/terser) to minify/minimize your JavaScript.
16+
This plugin minifies your assets in a webpack build. It ships with several
17+
built-in minimizers covering JavaScript, JSON, and HTML — pick one with the
18+
[`minify`](#minify) option and target the right files with [`test`](#test).
19+
20+
JavaScript minimizers:
21+
22+
- [`terser`](https://github.com/terser/terser)`TerserPlugin.terserMinify` (default). The same JavaScript-based minifier that webpack uses out of the box; produces small, well-tested output and supports the full set of `extractComments` modes.
23+
- [`uglify-js`](https://github.com/mishoo/UglifyJS)`TerserPlugin.uglifyJsMinify`. ES5-only minifier, useful when you specifically need UglifyJS-compatible output. Requires `npm install --save-dev uglify-js`.
24+
- [`@swc/core`](https://github.com/swc-project/swc)`TerserPlugin.swcMinify`. A very fast Rust-based JavaScript/TypeScript minifier. Requires `npm install --save-dev @swc/core`.
25+
- [`esbuild`](https://github.com/evanw/esbuild)`TerserPlugin.esbuildMinify`. An extremely fast JS bundler/minifier; legal comments are always preserved (no `extractComments` support). Requires `npm install --save-dev esbuild`.
26+
27+
JSON minimizer:
28+
29+
- `JSON.stringify``TerserPlugin.jsonMinify`. Built in (no extra dependency); supports `space` and `replacer` options.
30+
31+
HTML minimizers:
32+
33+
- [`html-minifier-terser`](https://github.com/terser/html-minifier-terser)`TerserPlugin.htmlMinifierTerser`. The default HTML minimizer. JavaScript-based, no native dependency. Requires `npm install --save-dev html-minifier-terser`.
34+
- [`@swc/html`](https://github.com/swc-project/swc)`TerserPlugin.swcMinifyHtml` (full HTML documents) and `TerserPlugin.swcMinifyHtmlFragment` (HTML fragments, e.g. `<template>` content). Very fast Rust-based platform for the Web. Requires `npm install --save-dev @swc/html`.
35+
- [`@minify-html/node`](https://github.com/wilsonzlin/minify-html)`TerserPlugin.minifyHtmlNode`. A Rust HTML minifier optimised for speed and effectiveness. Requires `npm install --save-dev @minify-html/node`.
36+
37+
All of the non-default minimizers are declared as **optional** peer
38+
dependencies — install only the ones you actually use. You can also stack
39+
multiple `TerserPlugin` instances in the same build to handle different
40+
file types with different minimizers (see [Examples](#examples)).
1741

1842
## Getting Started
1943

@@ -892,6 +916,155 @@ module.exports = {
892916
};
893917
```
894918

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

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

9481121
```ts
9491122
import { type JsMinifyOptions as SwcOptions } from "@swc/core";
1123+
import {
1124+
type FragmentOptions as SwcHtmlFragmentOptions,
1125+
type Options as SwcHtmlOptions,
1126+
} from "@swc/html";
9501127
import { type TransformOptions as EsbuildOptions } from "esbuild";
1128+
import { type Options as HtmlMinifierTerserOptions } from "html-minifier-terser";
9511129
import { type MinifyOptions as TerserOptions } from "terser";
9521130
import { type MinifyOptions as UglifyJSOptions } from "uglify-js";
9531131

@@ -981,6 +1159,29 @@ module.exports = {
9811159
// `terser` options
9821160
},
9831161
}),
1162+
1163+
// HTML minimizers
1164+
new TerserPlugin<HtmlMinifierTerserOptions>({
1165+
test: /\.html(\?.*)?$/i,
1166+
minify: TerserPlugin.htmlMinifierTerser,
1167+
minimizerOptions: {
1168+
// `html-minifier-terser` options
1169+
},
1170+
}),
1171+
new TerserPlugin<SwcHtmlOptions>({
1172+
test: /\.html(\?.*)?$/i,
1173+
minify: TerserPlugin.swcMinifyHtml,
1174+
minimizerOptions: {
1175+
// `@swc/html` options
1176+
},
1177+
}),
1178+
new TerserPlugin<SwcHtmlFragmentOptions>({
1179+
test: /\.template\.html$/i,
1180+
minify: TerserPlugin.swcMinifyHtmlFragment,
1181+
minimizerOptions: {
1182+
// `@swc/html` fragment options
1183+
},
1184+
}),
9841185
],
9851186
},
9861187
};

0 commit comments

Comments
 (0)