|
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 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)). |
17 | 41 |
|
18 | 42 | ## Getting Started |
19 | 43 |
|
@@ -892,6 +916,155 @@ module.exports = { |
892 | 916 | }; |
893 | 917 | ``` |
894 | 918 |
|
| 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 | + |
895 | 1068 | ### Custom Minify Function |
896 | 1069 |
|
897 | 1070 | Override the default minify function - use `uglify-js` for minification. |
@@ -947,7 +1120,12 @@ With built-in minify functions: |
947 | 1120 |
|
948 | 1121 | ```ts |
949 | 1122 | import { type JsMinifyOptions as SwcOptions } from "@swc/core"; |
| 1123 | +import { |
| 1124 | + type FragmentOptions as SwcHtmlFragmentOptions, |
| 1125 | + type Options as SwcHtmlOptions, |
| 1126 | +} from "@swc/html"; |
950 | 1127 | import { type TransformOptions as EsbuildOptions } from "esbuild"; |
| 1128 | +import { type Options as HtmlMinifierTerserOptions } from "html-minifier-terser"; |
951 | 1129 | import { type MinifyOptions as TerserOptions } from "terser"; |
952 | 1130 | import { type MinifyOptions as UglifyJSOptions } from "uglify-js"; |
953 | 1131 |
|
@@ -981,6 +1159,29 @@ module.exports = { |
981 | 1159 | // `terser` options |
982 | 1160 | }, |
983 | 1161 | }), |
| 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 | + }), |
984 | 1185 | ], |
985 | 1186 | }, |
986 | 1187 | }; |
|
0 commit comments