935 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			935 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| <div align="center">
 | |
|   <a href="https://github.com/webpack/webpack">
 | |
|     <img width="200" height="200" src="https://webpack.js.org/assets/icon-square-big.svg">
 | |
|   </a>
 | |
| </div>
 | |
| 
 | |
| [![npm][npm]][npm-url]
 | |
| [![node][node]][node-url]
 | |
| [![tests][tests]][tests-url]
 | |
| [![cover][cover]][cover-url]
 | |
| [![discussion][discussion]][discussion-url]
 | |
| [![size][size]][size-url]
 | |
| 
 | |
| # terser-webpack-plugin
 | |
| 
 | |
| This plugin uses [terser](https://github.com/terser/terser) to minify/minimize your JavaScript.
 | |
| 
 | |
| ## Getting Started
 | |
| 
 | |
| Webpack v5 comes with the latest `terser-webpack-plugin` out of the box. If you are using Webpack v5 or above and wish to customize the options, you will still need to install `terser-webpack-plugin`. Using Webpack v4, you have to install `terser-webpack-plugin` v4.
 | |
| 
 | |
| To begin, you'll need to install `terser-webpack-plugin`:
 | |
| 
 | |
| ```console
 | |
| npm install terser-webpack-plugin --save-dev
 | |
| ```
 | |
| 
 | |
| or
 | |
| 
 | |
| ```console
 | |
| yarn add -D terser-webpack-plugin
 | |
| ```
 | |
| 
 | |
| or
 | |
| 
 | |
| ```console
 | |
| pnpm add -D terser-webpack-plugin
 | |
| ```
 | |
| 
 | |
| Then add the plugin to your `webpack` config. For example:
 | |
| 
 | |
| **webpack.config.js**
 | |
| 
 | |
| ```js
 | |
| const TerserPlugin = require("terser-webpack-plugin");
 | |
| 
 | |
| module.exports = {
 | |
|   optimization: {
 | |
|     minimize: true,
 | |
|     minimizer: [new TerserPlugin()],
 | |
|   },
 | |
| };
 | |
| ```
 | |
| 
 | |
| And run `webpack` via your preferred method.
 | |
| 
 | |
| ## Note about source maps
 | |
| 
 | |
| **Works only with `source-map`, `inline-source-map`, `hidden-source-map` and `nosources-source-map` values for the [`devtool`](https://webpack.js.org/configuration/devtool/) option.**
 | |
| 
 | |
| Why?
 | |
| 
 | |
| - `eval` wraps modules in `eval("string")` and the minimizer does not handle strings.
 | |
| - `cheap` has not column information and minimizer generate only a single line, which leave only a single mapping.
 | |
| 
 | |
| Using supported `devtool` values enable source map generation.
 | |
| 
 | |
| ## Options
 | |
| 
 | |
| - **[`test`](#test)**
 | |
| - **[`include`](#include)**
 | |
| - **[`exclude`](#exclude)**
 | |
| - **[`parallel`](#parallel)**
 | |
| - **[`minify`](#minify)**
 | |
| - **[`terserOptions`](#terseroptions)**
 | |
| - **[`extractComments`](#extractcomments)**
 | |
| 
 | |
| ### `test`
 | |
| 
 | |
| Type:
 | |
| 
 | |
| ```ts
 | |
| type test = string | RegExp | Array<string | RegExp>;
 | |
| ```
 | |
| 
 | |
| Default: `/\.m?js(\?.*)?$/i`
 | |
| 
 | |
| Test to match files against.
 | |
| 
 | |
| **webpack.config.js**
 | |
| 
 | |
| ```js
 | |
| module.exports = {
 | |
|   optimization: {
 | |
|     minimize: true,
 | |
|     minimizer: [
 | |
|       new TerserPlugin({
 | |
|         test: /\.js(\?.*)?$/i,
 | |
|       }),
 | |
|     ],
 | |
|   },
 | |
| };
 | |
| ```
 | |
| 
 | |
| ### `include`
 | |
| 
 | |
| Type:
 | |
| 
 | |
| ```ts
 | |
| type include = string | RegExp | Array<string | RegExp>;
 | |
| ```
 | |
| 
 | |
| Default: `undefined`
 | |
| 
 | |
| Files to include.
 | |
| 
 | |
| **webpack.config.js**
 | |
| 
 | |
| ```js
 | |
| module.exports = {
 | |
|   optimization: {
 | |
|     minimize: true,
 | |
|     minimizer: [
 | |
|       new TerserPlugin({
 | |
|         include: /\/includes/,
 | |
|       }),
 | |
|     ],
 | |
|   },
 | |
| };
 | |
| ```
 | |
| 
 | |
| ### `exclude`
 | |
| 
 | |
| Type:
 | |
| 
 | |
| ```ts
 | |
| type exclude = string | RegExp | Array<string | RegExp>;
 | |
| ```
 | |
| 
 | |
| Default: `undefined`
 | |
| 
 | |
| Files to exclude.
 | |
| 
 | |
| **webpack.config.js**
 | |
| 
 | |
| ```js
 | |
| module.exports = {
 | |
|   optimization: {
 | |
|     minimize: true,
 | |
|     minimizer: [
 | |
|       new TerserPlugin({
 | |
|         exclude: /\/excludes/,
 | |
|       }),
 | |
|     ],
 | |
|   },
 | |
| };
 | |
| ```
 | |
| 
 | |
| ### `parallel`
 | |
| 
 | |
| Type:
 | |
| 
 | |
| ```ts
 | |
| type parallel = boolean | number;
 | |
| ```
 | |
| 
 | |
| Default: `true`
 | |
| 
 | |
| Use multi-process parallel running to improve the build speed.
 | |
| Default number of concurrent runs: `os.cpus().length - 1` or `os.availableParallelism() - 1` (if this function is supported).
 | |
| 
 | |
| > **Note**
 | |
| >
 | |
| > Parallelization can speedup your build significantly and is therefore **highly recommended**.
 | |
| 
 | |
| > **Warning**
 | |
| >
 | |
| > If you use **Circle CI** or any other environment that doesn't provide real available count of CPUs then you need to setup explicitly number of CPUs to avoid `Error: Call retries were exceeded` (see [#143](https://github.com/webpack-contrib/terser-webpack-plugin/issues/143), [#202](https://github.com/webpack-contrib/terser-webpack-plugin/issues/202)).
 | |
| 
 | |
| #### `boolean`
 | |
| 
 | |
| Enable/disable multi-process parallel running.
 | |
| 
 | |
| **webpack.config.js**
 | |
| 
 | |
| ```js
 | |
| module.exports = {
 | |
|   optimization: {
 | |
|     minimize: true,
 | |
|     minimizer: [
 | |
|       new TerserPlugin({
 | |
|         parallel: true,
 | |
|       }),
 | |
|     ],
 | |
|   },
 | |
| };
 | |
| ```
 | |
| 
 | |
| #### `number`
 | |
| 
 | |
| Enable multi-process parallel running and set number of concurrent runs.
 | |
| 
 | |
| **webpack.config.js**
 | |
| 
 | |
| ```js
 | |
| module.exports = {
 | |
|   optimization: {
 | |
|     minimize: true,
 | |
|     minimizer: [
 | |
|       new TerserPlugin({
 | |
|         parallel: 4,
 | |
|       }),
 | |
|     ],
 | |
|   },
 | |
| };
 | |
| ```
 | |
| 
 | |
| ### `minify`
 | |
| 
 | |
| Type:
 | |
| 
 | |
| ```ts
 | |
| type minify = (
 | |
|   input: {
 | |
|     [file: string]: string;
 | |
|   },
 | |
|   sourceMap: import("@jridgewell/trace-mapping").SourceMapInput | undefined,
 | |
|   minifyOptions: {
 | |
|     module?: boolean | undefined;
 | |
|     ecma?: import("terser").ECMA | undefined;
 | |
|   },
 | |
|   extractComments:
 | |
|     | boolean
 | |
|     | "all"
 | |
|     | "some"
 | |
|     | RegExp
 | |
|     | ((
 | |
|         astNode: any,
 | |
|         comment: {
 | |
|           value: string;
 | |
|           type: "comment1" | "comment2" | "comment3" | "comment4";
 | |
|           pos: number;
 | |
|           line: number;
 | |
|           col: number;
 | |
|         }
 | |
|       ) => boolean)
 | |
|     | {
 | |
|         condition?:
 | |
|           | boolean
 | |
|           | "all"
 | |
|           | "some"
 | |
|           | RegExp
 | |
|           | ((
 | |
|               astNode: any,
 | |
|               comment: {
 | |
|                 value: string;
 | |
|                 type: "comment1" | "comment2" | "comment3" | "comment4";
 | |
|                 pos: number;
 | |
|                 line: number;
 | |
|                 col: number;
 | |
|               }
 | |
|             ) => boolean)
 | |
|           | undefined;
 | |
|         filename?: string | ((fileData: any) => string) | undefined;
 | |
|         banner?:
 | |
|           | string
 | |
|           | boolean
 | |
|           | ((commentsFile: string) => string)
 | |
|           | undefined;
 | |
|       }
 | |
|     | undefined
 | |
| ) => Promise<{
 | |
|   code: string;
 | |
|   map?: import("@jridgewell/trace-mapping").SourceMapInput | undefined;
 | |
|   errors?: (string | Error)[] | undefined;
 | |
|   warnings?: (string | Error)[] | undefined;
 | |
|   extractedComments?: string[] | undefined;
 | |
| }>;
 | |
| ```
 | |
| 
 | |
| Default: `TerserPlugin.terserMinify`
 | |
| 
 | |
| Allows you to override default minify function.
 | |
| By default plugin uses [terser](https://github.com/terser/terser) package.
 | |
| Useful for using and testing unpublished versions or forks.
 | |
| 
 | |
| > **Warning**
 | |
| >
 | |
| > **Always use `require` inside `minify` function when `parallel` option enabled**.
 | |
| 
 | |
| **webpack.config.js**
 | |
| 
 | |
| ```js
 | |
| // Can be async
 | |
| const minify = (input, sourceMap, minimizerOptions, extractsComments) => {
 | |
|   // The `minimizerOptions` option contains option from the `terserOptions` option
 | |
|   // You can use `minimizerOptions.myCustomOption`
 | |
| 
 | |
|   // Custom logic for extract comments
 | |
|   const { map, code } = require("uglify-module") // Or require('./path/to/uglify-module')
 | |
|     .minify(input, {
 | |
|       /* Your options for minification */
 | |
|     });
 | |
| 
 | |
|   return { map, code, warnings: [], errors: [], extractedComments: [] };
 | |
| };
 | |
| 
 | |
| // Used to regenerate `fullhash`/`chunkhash` between different implementation
 | |
| // Example: you fix a bug in custom minimizer/custom function, but unfortunately webpack doesn't know about it, so you will get the same fullhash/chunkhash
 | |
| // to avoid this you can provide version of your custom minimizer
 | |
| // You don't need if you use only `contenthash`
 | |
| minify.getMinimizerVersion = () => {
 | |
|   let packageJson;
 | |
| 
 | |
|   try {
 | |
|     // eslint-disable-next-line global-require, import/no-extraneous-dependencies
 | |
|     packageJson = require("uglify-module/package.json");
 | |
|   } catch (error) {
 | |
|     // Ignore
 | |
|   }
 | |
| 
 | |
|   return packageJson && packageJson.version;
 | |
| };
 | |
| 
 | |
| module.exports = {
 | |
|   optimization: {
 | |
|     minimize: true,
 | |
|     minimizer: [
 | |
|       new TerserPlugin({
 | |
|         terserOptions: {
 | |
|           myCustomOption: true,
 | |
|         },
 | |
|         minify,
 | |
|       }),
 | |
|     ],
 | |
|   },
 | |
| };
 | |
| ```
 | |
| 
 | |
| ### `terserOptions`
 | |
| 
 | |
| Type:
 | |
| 
 | |
| ```ts
 | |
| type terserOptions = {
 | |
|   compress?: boolean | CompressOptions;
 | |
|   ecma?: ECMA;
 | |
|   enclose?: boolean | string;
 | |
|   ie8?: boolean;
 | |
|   keep_classnames?: boolean | RegExp;
 | |
|   keep_fnames?: boolean | RegExp;
 | |
|   mangle?: boolean | MangleOptions;
 | |
|   module?: boolean;
 | |
|   nameCache?: object;
 | |
|   format?: FormatOptions;
 | |
|   /** @deprecated */
 | |
|   output?: FormatOptions;
 | |
|   parse?: ParseOptions;
 | |
|   safari10?: boolean;
 | |
|   sourceMap?: boolean | SourceMapOptions;
 | |
|   toplevel?: boolean;
 | |
| };
 | |
| ```
 | |
| 
 | |
| Default: [default](https://github.com/terser/terser#minify-options)
 | |
| 
 | |
| Terser [options](https://github.com/terser/terser#minify-options).
 | |
| 
 | |
| **webpack.config.js**
 | |
| 
 | |
| ```js
 | |
| module.exports = {
 | |
|   optimization: {
 | |
|     minimize: true,
 | |
|     minimizer: [
 | |
|       new TerserPlugin({
 | |
|         terserOptions: {
 | |
|           ecma: undefined,
 | |
|           parse: {},
 | |
|           compress: {},
 | |
|           mangle: true, // Note `mangle.properties` is `false` by default.
 | |
|           module: false,
 | |
|           // Deprecated
 | |
|           output: null,
 | |
|           format: null,
 | |
|           toplevel: false,
 | |
|           nameCache: null,
 | |
|           ie8: false,
 | |
|           keep_classnames: undefined,
 | |
|           keep_fnames: false,
 | |
|           safari10: false,
 | |
|         },
 | |
|       }),
 | |
|     ],
 | |
|   },
 | |
| };
 | |
| ```
 | |
| 
 | |
| ### `extractComments`
 | |
| 
 | |
| Type:
 | |
| 
 | |
| ```ts
 | |
| type extractComments =
 | |
|   | boolean
 | |
|   | string
 | |
|   | RegExp
 | |
|   | ((
 | |
|       astNode: any,
 | |
|       comment: {
 | |
|         value: string;
 | |
|         type: "comment1" | "comment2" | "comment3" | "comment4";
 | |
|         pos: number;
 | |
|         line: number;
 | |
|         col: number;
 | |
|       }
 | |
|     ) => boolean)
 | |
|   | {
 | |
|       condition?:
 | |
|         | boolean
 | |
|         | "all"
 | |
|         | "some"
 | |
|         | RegExp
 | |
|         | ((
 | |
|             astNode: any,
 | |
|             comment: {
 | |
|               value: string;
 | |
|               type: "comment1" | "comment2" | "comment3" | "comment4";
 | |
|               pos: number;
 | |
|               line: number;
 | |
|               col: number;
 | |
|             }
 | |
|           ) => boolean)
 | |
|         | undefined;
 | |
|       filename?: string | ((fileData: any) => string) | undefined;
 | |
|       banner?:
 | |
|         | string
 | |
|         | boolean
 | |
|         | ((commentsFile: string) => string)
 | |
|         | undefined;
 | |
|     };
 | |
| ```
 | |
| 
 | |
| Default: `true`
 | |
| 
 | |
| Whether comments shall be extracted to a separate file, (see [details](https://github.com/webpack/webpack/commit/71933e979e51c533b432658d5e37917f9e71595a)).
 | |
| By default extract only comments using `/^\**!|@preserve|@license|@cc_on/i` regexp condition and remove remaining comments.
 | |
| If the original file is named `foo.js`, then the comments will be stored to `foo.js.LICENSE.txt`.
 | |
| The `terserOptions.format.comments` option specifies whether the comment will be preserved, i.e. it is possible to preserve some comments (e.g. annotations) while extracting others or even preserving comments that have been extracted.
 | |
| 
 | |
| #### `boolean`
 | |
| 
 | |
| Enable/disable extracting comments.
 | |
| 
 | |
| **webpack.config.js**
 | |
| 
 | |
| ```js
 | |
| module.exports = {
 | |
|   optimization: {
 | |
|     minimize: true,
 | |
|     minimizer: [
 | |
|       new TerserPlugin({
 | |
|         extractComments: true,
 | |
|       }),
 | |
|     ],
 | |
|   },
 | |
| };
 | |
| ```
 | |
| 
 | |
| #### `string`
 | |
| 
 | |
| Extract `all` or `some` (use `/^\**!|@preserve|@license|@cc_on/i` RegExp) comments.
 | |
| 
 | |
| **webpack.config.js**
 | |
| 
 | |
| ```js
 | |
| module.exports = {
 | |
|   optimization: {
 | |
|     minimize: true,
 | |
|     minimizer: [
 | |
|       new TerserPlugin({
 | |
|         extractComments: "all",
 | |
|       }),
 | |
|     ],
 | |
|   },
 | |
| };
 | |
| ```
 | |
| 
 | |
| #### `RegExp`
 | |
| 
 | |
| All comments that match the given expression will be extracted to the separate file.
 | |
| 
 | |
| **webpack.config.js**
 | |
| 
 | |
| ```js
 | |
| module.exports = {
 | |
|   optimization: {
 | |
|     minimize: true,
 | |
|     minimizer: [
 | |
|       new TerserPlugin({
 | |
|         extractComments: /@extract/i,
 | |
|       }),
 | |
|     ],
 | |
|   },
 | |
| };
 | |
| ```
 | |
| 
 | |
| #### `function`
 | |
| 
 | |
| All comments that match the given expression will be extracted to the separate file.
 | |
| 
 | |
| **webpack.config.js**
 | |
| 
 | |
| ```js
 | |
| module.exports = {
 | |
|   optimization: {
 | |
|     minimize: true,
 | |
|     minimizer: [
 | |
|       new TerserPlugin({
 | |
|         extractComments: (astNode, comment) => {
 | |
|           if (/@extract/i.test(comment.value)) {
 | |
|             return true;
 | |
|           }
 | |
| 
 | |
|           return false;
 | |
|         },
 | |
|       }),
 | |
|     ],
 | |
|   },
 | |
| };
 | |
| ```
 | |
| 
 | |
| #### `object`
 | |
| 
 | |
| Allow to customize condition for extract comments, specify extracted file name and banner.
 | |
| 
 | |
| **webpack.config.js**
 | |
| 
 | |
| ```js
 | |
| module.exports = {
 | |
|   optimization: {
 | |
|     minimize: true,
 | |
|     minimizer: [
 | |
|       new TerserPlugin({
 | |
|         extractComments: {
 | |
|           condition: /^\**!|@preserve|@license|@cc_on/i,
 | |
|           filename: (fileData) => {
 | |
|             // The "fileData" argument contains object with "filename", "basename", "query" and "hash"
 | |
|             return `${fileData.filename}.LICENSE.txt${fileData.query}`;
 | |
|           },
 | |
|           banner: (licenseFile) => {
 | |
|             return `License information can be found in ${licenseFile}`;
 | |
|           },
 | |
|         },
 | |
|       }),
 | |
|     ],
 | |
|   },
 | |
| };
 | |
| ```
 | |
| 
 | |
| ##### `condition`
 | |
| 
 | |
| Type:
 | |
| 
 | |
| ```ts
 | |
| type condition =
 | |
|   | boolean
 | |
|   | "all"
 | |
|   | "some"
 | |
|   | RegExp
 | |
|   | ((
 | |
|       astNode: any,
 | |
|       comment: {
 | |
|         value: string;
 | |
|         type: "comment1" | "comment2" | "comment3" | "comment4";
 | |
|         pos: number;
 | |
|         line: number;
 | |
|         col: number;
 | |
|       }
 | |
|     ) => boolean)
 | |
|   | undefined;
 | |
| ```
 | |
| 
 | |
| Condition what comments you need extract.
 | |
| 
 | |
| **webpack.config.js**
 | |
| 
 | |
| ```js
 | |
| module.exports = {
 | |
|   optimization: {
 | |
|     minimize: true,
 | |
|     minimizer: [
 | |
|       new TerserPlugin({
 | |
|         extractComments: {
 | |
|           condition: "some",
 | |
|           filename: (fileData) => {
 | |
|             // The "fileData" argument contains object with "filename", "basename", "query" and "hash"
 | |
|             return `${fileData.filename}.LICENSE.txt${fileData.query}`;
 | |
|           },
 | |
|           banner: (licenseFile) => {
 | |
|             return `License information can be found in ${licenseFile}`;
 | |
|           },
 | |
|         },
 | |
|       }),
 | |
|     ],
 | |
|   },
 | |
| };
 | |
| ```
 | |
| 
 | |
| ##### `filename`
 | |
| 
 | |
| Type:
 | |
| 
 | |
| ```ts
 | |
| type filename = string | ((fileData: any) => string) | undefined;
 | |
| ```
 | |
| 
 | |
| Default: `[file].LICENSE.txt[query]`
 | |
| 
 | |
| Available placeholders: `[file]`, `[query]` and `[filebase]` (`[base]` for webpack 5).
 | |
| 
 | |
| The file where the extracted comments will be stored.
 | |
| Default is to append the suffix `.LICENSE.txt` to the original filename.
 | |
| 
 | |
| > **Warning**
 | |
| >
 | |
| > We highly recommend using the `txt` extension. Using `js`/`cjs`/`mjs` extensions may conflict with existing assets which leads to broken code.
 | |
| 
 | |
| **webpack.config.js**
 | |
| 
 | |
| ```js
 | |
| module.exports = {
 | |
|   optimization: {
 | |
|     minimize: true,
 | |
|     minimizer: [
 | |
|       new TerserPlugin({
 | |
|         extractComments: {
 | |
|           condition: /^\**!|@preserve|@license|@cc_on/i,
 | |
|           filename: "extracted-comments.js",
 | |
|           banner: (licenseFile) => {
 | |
|             return `License information can be found in ${licenseFile}`;
 | |
|           },
 | |
|         },
 | |
|       }),
 | |
|     ],
 | |
|   },
 | |
| };
 | |
| ```
 | |
| 
 | |
| ##### `banner`
 | |
| 
 | |
| Type:
 | |
| 
 | |
| ```ts
 | |
| type banner = string | boolean | ((commentsFile: string) => string) | undefined;
 | |
| ```
 | |
| 
 | |
| Default: `/*! For license information please see ${commentsFile} */`
 | |
| 
 | |
| The banner text that points to the extracted file and will be added on top of the original file.
 | |
| Can be `false` (no banner), a `String`, or a `Function<(string) -> String>` that will be called with the filename where extracted comments have been stored.
 | |
| Will be wrapped into comment.
 | |
| 
 | |
| **webpack.config.js**
 | |
| 
 | |
| ```js
 | |
| module.exports = {
 | |
|   optimization: {
 | |
|     minimize: true,
 | |
|     minimizer: [
 | |
|       new TerserPlugin({
 | |
|         extractComments: {
 | |
|           condition: true,
 | |
|           filename: (fileData) => {
 | |
|             // The "fileData" argument contains object with "filename", "basename", "query" and "hash"
 | |
|             return `${fileData.filename}.LICENSE.txt${fileData.query}`;
 | |
|           },
 | |
|           banner: (commentsFile) => {
 | |
|             return `My custom banner about license information ${commentsFile}`;
 | |
|           },
 | |
|         },
 | |
|       }),
 | |
|     ],
 | |
|   },
 | |
| };
 | |
| ```
 | |
| 
 | |
| ## Examples
 | |
| 
 | |
| ### Preserve Comments
 | |
| 
 | |
| Extract all legal comments (i.e. `/^\**!|@preserve|@license|@cc_on/i`) and preserve `/@license/i` comments.
 | |
| 
 | |
| **webpack.config.js**
 | |
| 
 | |
| ```js
 | |
| module.exports = {
 | |
|   optimization: {
 | |
|     minimize: true,
 | |
|     minimizer: [
 | |
|       new TerserPlugin({
 | |
|         terserOptions: {
 | |
|           format: {
 | |
|             comments: /@license/i,
 | |
|           },
 | |
|         },
 | |
|         extractComments: true,
 | |
|       }),
 | |
|     ],
 | |
|   },
 | |
| };
 | |
| ```
 | |
| 
 | |
| ### Remove Comments
 | |
| 
 | |
| If you avoid building with comments, use this config:
 | |
| 
 | |
| **webpack.config.js**
 | |
| 
 | |
| ```js
 | |
| module.exports = {
 | |
|   optimization: {
 | |
|     minimize: true,
 | |
|     minimizer: [
 | |
|       new TerserPlugin({
 | |
|         terserOptions: {
 | |
|           format: {
 | |
|             comments: false,
 | |
|           },
 | |
|         },
 | |
|         extractComments: false,
 | |
|       }),
 | |
|     ],
 | |
|   },
 | |
| };
 | |
| ```
 | |
| 
 | |
| ### [`uglify-js`](https://github.com/mishoo/UglifyJS)
 | |
| 
 | |
| [`UglifyJS`](https://github.com/mishoo/UglifyJS) is a JavaScript parser, minifier, compressor and beautifier toolkit.
 | |
| 
 | |
| **webpack.config.js**
 | |
| 
 | |
| ```js
 | |
| module.exports = {
 | |
|   optimization: {
 | |
|     minimize: true,
 | |
|     minimizer: [
 | |
|       new TerserPlugin({
 | |
|         minify: TerserPlugin.uglifyJsMinify,
 | |
|         // `terserOptions` options will be passed to `uglify-js`
 | |
|         // Link to options - https://github.com/mishoo/UglifyJS#minify-options
 | |
|         terserOptions: {},
 | |
|       }),
 | |
|     ],
 | |
|   },
 | |
| };
 | |
| ```
 | |
| 
 | |
| ### [`swc`](https://github.com/swc-project/swc)
 | |
| 
 | |
| [`swc`](https://github.com/swc-project/swc) is a super-fast compiler written in rust; producing widely-supported javascript from modern standards and typescript.
 | |
| 
 | |
| > **Warning**
 | |
| >
 | |
| > the `extractComments` option is not supported and all comments will be removed by default, it will be fixed in future
 | |
| 
 | |
| **webpack.config.js**
 | |
| 
 | |
| ```js
 | |
| module.exports = {
 | |
|   optimization: {
 | |
|     minimize: true,
 | |
|     minimizer: [
 | |
|       new TerserPlugin({
 | |
|         minify: TerserPlugin.swcMinify,
 | |
|         // `terserOptions` options will be passed to `swc` (`@swc/core`)
 | |
|         // Link to options - https://swc.rs/docs/config-js-minify
 | |
|         terserOptions: {},
 | |
|       }),
 | |
|     ],
 | |
|   },
 | |
| };
 | |
| ```
 | |
| 
 | |
| ### [`esbuild`](https://github.com/evanw/esbuild)
 | |
| 
 | |
| [`esbuild`](https://github.com/evanw/esbuild) is an extremely fast JavaScript bundler and minifier.
 | |
| 
 | |
| > **Warning**
 | |
| >
 | |
| > the `extractComments` option is not supported and all legal comments (i.e. copyright, licenses and etc) will be preserved
 | |
| 
 | |
| **webpack.config.js**
 | |
| 
 | |
| ```js
 | |
| module.exports = {
 | |
|   optimization: {
 | |
|     minimize: true,
 | |
|     minimizer: [
 | |
|       new TerserPlugin({
 | |
|         minify: TerserPlugin.esbuildMinify,
 | |
|         // `terserOptions` options will be passed to `esbuild`
 | |
|         // Link to options - https://esbuild.github.io/api/#minify
 | |
|         // Note: the `minify` options is true by default (and override other `minify*` options), so if you want to disable the `minifyIdentifiers` option (or other `minify*` options) please use:
 | |
|         // terserOptions: {
 | |
|         //   minify: false,
 | |
|         //   minifyWhitespace: true,
 | |
|         //   minifyIdentifiers: false,
 | |
|         //   minifySyntax: true,
 | |
|         // },
 | |
|         terserOptions: {},
 | |
|       }),
 | |
|     ],
 | |
|   },
 | |
| };
 | |
| ```
 | |
| 
 | |
| ### Custom Minify Function
 | |
| 
 | |
| Override default minify function - use `uglify-js` for minification.
 | |
| 
 | |
| **webpack.config.js**
 | |
| 
 | |
| ```js
 | |
| module.exports = {
 | |
|   optimization: {
 | |
|     minimize: true,
 | |
|     minimizer: [
 | |
|       new TerserPlugin({
 | |
|         minify: (file, sourceMap) => {
 | |
|           // https://github.com/mishoo/UglifyJS2#minify-options
 | |
|           const uglifyJsOptions = {
 | |
|             /* your `uglify-js` package options */
 | |
|           };
 | |
| 
 | |
|           if (sourceMap) {
 | |
|             uglifyJsOptions.sourceMap = {
 | |
|               content: sourceMap,
 | |
|             };
 | |
|           }
 | |
| 
 | |
|           return require("uglify-js").minify(file, uglifyJsOptions);
 | |
|         },
 | |
|       }),
 | |
|     ],
 | |
|   },
 | |
| };
 | |
| ```
 | |
| 
 | |
| ### Typescript
 | |
| 
 | |
| With default terser minify function:
 | |
| 
 | |
| ```ts
 | |
| module.exports = {
 | |
|   optimization: {
 | |
|     minimize: true,
 | |
|     minimizer: [
 | |
|       new TerserPlugin({
 | |
|         terserOptions: {
 | |
|           compress: true,
 | |
|         },
 | |
|       }),
 | |
|     ],
 | |
|   },
 | |
| };
 | |
| ```
 | |
| 
 | |
| With built-in minify functions:
 | |
| 
 | |
| ```ts
 | |
| import type { JsMinifyOptions as SwcOptions } from "@swc/core";
 | |
| import type { MinifyOptions as UglifyJSOptions } from "uglify-js";
 | |
| import type { TransformOptions as EsbuildOptions } from "esbuild";
 | |
| import type { MinifyOptions as TerserOptions } from "terser";
 | |
| 
 | |
| module.exports = {
 | |
|   optimization: {
 | |
|     minimize: true,
 | |
|     minimizer: [
 | |
|       new TerserPlugin<SwcOptions>({
 | |
|         minify: TerserPlugin.swcMinify,
 | |
|         terserOptions: {
 | |
|           // `swc` options
 | |
|         },
 | |
|       }),
 | |
|       new TerserPlugin<UglifyJSOptions>({
 | |
|         minify: TerserPlugin.uglifyJsMinify,
 | |
|         terserOptions: {
 | |
|           // `uglif-js` options
 | |
|         },
 | |
|       }),
 | |
|       new TerserPlugin<EsbuildOptions>({
 | |
|         minify: TerserPlugin.esbuildMinify,
 | |
|         terserOptions: {
 | |
|           // `esbuild` options
 | |
|         },
 | |
|       }),
 | |
| 
 | |
|       // Alternative usage:
 | |
|       new TerserPlugin<TerserOptions>({
 | |
|         minify: TerserPlugin.terserMinify,
 | |
|         terserOptions: {
 | |
|           // `terser` options
 | |
|         },
 | |
|       }),
 | |
|     ],
 | |
|   },
 | |
| };
 | |
| ```
 | |
| 
 | |
| ## Contributing
 | |
| 
 | |
| Please take a moment to read our contributing guidelines if you haven't yet done so.
 | |
| 
 | |
| [CONTRIBUTING](./.github/CONTRIBUTING.md)
 | |
| 
 | |
| ## License
 | |
| 
 | |
| [MIT](./LICENSE)
 | |
| 
 | |
| [npm]: https://img.shields.io/npm/v/terser-webpack-plugin.svg
 | |
| [npm-url]: https://npmjs.com/package/terser-webpack-plugin
 | |
| [node]: https://img.shields.io/node/v/terser-webpack-plugin.svg
 | |
| [node-url]: https://nodejs.org
 | |
| [tests]: https://github.com/webpack-contrib/terser-webpack-plugin/workflows/terser-webpack-plugin/badge.svg
 | |
| [tests-url]: https://github.com/webpack-contrib/terser-webpack-plugin/actions
 | |
| [cover]: https://codecov.io/gh/webpack-contrib/terser-webpack-plugin/branch/master/graph/badge.svg
 | |
| [cover-url]: https://codecov.io/gh/webpack-contrib/terser-webpack-plugin
 | |
| [discussion]: https://img.shields.io/github/discussions/webpack/webpack
 | |
| [discussion-url]: https://github.com/webpack/webpack/discussions
 | |
| [size]: https://packagephobia.now.sh/badge?p=terser-webpack-plugin
 | |
| [size-url]: https://packagephobia.now.sh/result?p=terser-webpack-plugin
 |