|
13 | 13 |
|
14 | 14 | # terser-webpack-plugin |
15 | 15 |
|
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. |
17 | 23 |
|
18 | 24 | ## Getting Started |
19 | 25 |
|
@@ -892,6 +898,155 @@ module.exports = { |
892 | 898 | }; |
893 | 899 | ``` |
894 | 900 |
|
| 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 | + |
895 | 1050 | ### Custom Minify Function |
896 | 1051 |
|
897 | 1052 | Override the default minify function - use `uglify-js` for minification. |
@@ -947,7 +1102,12 @@ With built-in minify functions: |
947 | 1102 |
|
948 | 1103 | ```ts |
949 | 1104 | import { type JsMinifyOptions as SwcOptions } from "@swc/core"; |
| 1105 | +import { |
| 1106 | + type FragmentOptions as SwcHtmlFragmentOptions, |
| 1107 | + type Options as SwcHtmlOptions, |
| 1108 | +} from "@swc/html"; |
950 | 1109 | import { type TransformOptions as EsbuildOptions } from "esbuild"; |
| 1110 | +import { type Options as HtmlMinifierTerserOptions } from "html-minifier-terser"; |
951 | 1111 | import { type MinifyOptions as TerserOptions } from "terser"; |
952 | 1112 | import { type MinifyOptions as UglifyJSOptions } from "uglify-js"; |
953 | 1113 |
|
@@ -981,6 +1141,29 @@ module.exports = { |
981 | 1141 | // `terser` options |
982 | 1142 | }, |
983 | 1143 | }), |
| 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 | + }), |
984 | 1167 | ], |
985 | 1168 | }, |
986 | 1169 | }; |
|
0 commit comments