1 | <div align="center">
|
2 | <a href="https://github.com/webpack/webpack">
|
3 | <img width="200" height="200" src="https://webpack.js.org/assets/icon-square-big.svg">
|
4 | </a>
|
5 | </div>
|
6 |
|
7 | [![npm][npm]][npm-url]
|
8 | [![node][node]][node-url]
|
9 | [![tests][tests]][tests-url]
|
10 | [![cover][cover]][cover-url]
|
11 | [![discussion][discussion]][discussion-url]
|
12 | [![size][size]][size-url]
|
13 |
|
14 | # terser-webpack-plugin
|
15 |
|
16 | This plugin uses [terser](https://github.com/terser/terser) to minify/minimize your JavaScript.
|
17 |
|
18 | ## Getting Started
|
19 |
|
20 | 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.
|
21 |
|
22 | To begin, you'll need to install `terser-webpack-plugin`:
|
23 |
|
24 | ```console
|
25 | npm install terser-webpack-plugin --save-dev
|
26 | ```
|
27 |
|
28 | or
|
29 |
|
30 | ```console
|
31 | yarn add -D terser-webpack-plugin
|
32 | ```
|
33 |
|
34 | or
|
35 |
|
36 | ```console
|
37 | pnpm add -D terser-webpack-plugin
|
38 | ```
|
39 |
|
40 | Then add the plugin to your `webpack` config. For example:
|
41 |
|
42 | **webpack.config.js**
|
43 |
|
44 | ```js
|
45 | const TerserPlugin = require("terser-webpack-plugin");
|
46 |
|
47 | module.exports = {
|
48 | optimization: {
|
49 | minimize: true,
|
50 | minimizer: [new TerserPlugin()],
|
51 | },
|
52 | };
|
53 | ```
|
54 |
|
55 | And run `webpack` via your preferred method.
|
56 |
|
57 | ## Note about source maps
|
58 |
|
59 | **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.**
|
60 |
|
61 | Why?
|
62 |
|
63 | - `eval` wraps modules in `eval("string")` and the minimizer does not handle strings.
|
64 | - `cheap` has not column information and minimizer generate only a single line, which leave only a single mapping.
|
65 |
|
66 | Using supported `devtool` values enable source map generation.
|
67 |
|
68 | ## Options
|
69 |
|
70 | - **[`test`](#test)**
|
71 | - **[`include`](#include)**
|
72 | - **[`exclude`](#exclude)**
|
73 | - **[`parallel`](#parallel)**
|
74 | - **[`minify`](#minify)**
|
75 | - **[`terserOptions`](#terseroptions)**
|
76 | - **[`extractComments`](#extractcomments)**
|
77 |
|
78 | ### `test`
|
79 |
|
80 | Type:
|
81 |
|
82 | ```ts
|
83 | type test = string | RegExp | Array<string | RegExp>;
|
84 | ```
|
85 |
|
86 | Default: `/\.m?js(\?.*)?$/i`
|
87 |
|
88 | Test to match files against.
|
89 |
|
90 | **webpack.config.js**
|
91 |
|
92 | ```js
|
93 | module.exports = {
|
94 | optimization: {
|
95 | minimize: true,
|
96 | minimizer: [
|
97 | new TerserPlugin({
|
98 | test: /\.js(\?.*)?$/i,
|
99 | }),
|
100 | ],
|
101 | },
|
102 | };
|
103 | ```
|
104 |
|
105 | ### `include`
|
106 |
|
107 | Type:
|
108 |
|
109 | ```ts
|
110 | type include = string | RegExp | Array<string | RegExp>;
|
111 | ```
|
112 |
|
113 | Default: `undefined`
|
114 |
|
115 | Files to include.
|
116 |
|
117 | **webpack.config.js**
|
118 |
|
119 | ```js
|
120 | module.exports = {
|
121 | optimization: {
|
122 | minimize: true,
|
123 | minimizer: [
|
124 | new TerserPlugin({
|
125 | include: /\/includes/,
|
126 | }),
|
127 | ],
|
128 | },
|
129 | };
|
130 | ```
|
131 |
|
132 | ### `exclude`
|
133 |
|
134 | Type:
|
135 |
|
136 | ```ts
|
137 | type exclude = string | RegExp | Array<string | RegExp>;
|
138 | ```
|
139 |
|
140 | Default: `undefined`
|
141 |
|
142 | Files to exclude.
|
143 |
|
144 | **webpack.config.js**
|
145 |
|
146 | ```js
|
147 | module.exports = {
|
148 | optimization: {
|
149 | minimize: true,
|
150 | minimizer: [
|
151 | new TerserPlugin({
|
152 | exclude: /\/excludes/,
|
153 | }),
|
154 | ],
|
155 | },
|
156 | };
|
157 | ```
|
158 |
|
159 | ### `parallel`
|
160 |
|
161 | Type:
|
162 |
|
163 | ```ts
|
164 | type parallel = boolean | number;
|
165 | ```
|
166 |
|
167 | Default: `true`
|
168 |
|
169 | Use multi-process parallel running to improve the build speed.
|
170 | Default number of concurrent runs: `os.cpus().length - 1`.
|
171 |
|
172 | > **Note**
|
173 | >
|
174 | > Parallelization can speedup your build significantly and is therefore **highly recommended**.
|
175 |
|
176 | > **Warning**
|
177 | >
|
178 | > 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)).
|
179 |
|
180 | #### `boolean`
|
181 |
|
182 | Enable/disable multi-process parallel running.
|
183 |
|
184 | **webpack.config.js**
|
185 |
|
186 | ```js
|
187 | module.exports = {
|
188 | optimization: {
|
189 | minimize: true,
|
190 | minimizer: [
|
191 | new TerserPlugin({
|
192 | parallel: true,
|
193 | }),
|
194 | ],
|
195 | },
|
196 | };
|
197 | ```
|
198 |
|
199 | #### `number`
|
200 |
|
201 | Enable multi-process parallel running and set number of concurrent runs.
|
202 |
|
203 | **webpack.config.js**
|
204 |
|
205 | ```js
|
206 | module.exports = {
|
207 | optimization: {
|
208 | minimize: true,
|
209 | minimizer: [
|
210 | new TerserPlugin({
|
211 | parallel: 4,
|
212 | }),
|
213 | ],
|
214 | },
|
215 | };
|
216 | ```
|
217 |
|
218 | ### `minify`
|
219 |
|
220 | Type:
|
221 |
|
222 | ```ts
|
223 | type minify = (
|
224 | input: {
|
225 | [file: string]: string;
|
226 | },
|
227 | sourceMap: import("@jridgewell/trace-mapping").SourceMapInput | undefined,
|
228 | minifyOptions: {
|
229 | module?: boolean | undefined;
|
230 | ecma?: import("terser").ECMA | undefined;
|
231 | },
|
232 | extractComments:
|
233 | | boolean
|
234 | | "all"
|
235 | | "some"
|
236 | | RegExp
|
237 | | ((
|
238 | astNode: any,
|
239 | comment: {
|
240 | value: string;
|
241 | type: "comment1" | "comment2" | "comment3" | "comment4";
|
242 | pos: number;
|
243 | line: number;
|
244 | col: number;
|
245 | }
|
246 | ) => boolean)
|
247 | | {
|
248 | condition?:
|
249 | | boolean
|
250 | | "all"
|
251 | | "some"
|
252 | | RegExp
|
253 | | ((
|
254 | astNode: any,
|
255 | comment: {
|
256 | value: string;
|
257 | type: "comment1" | "comment2" | "comment3" | "comment4";
|
258 | pos: number;
|
259 | line: number;
|
260 | col: number;
|
261 | }
|
262 | ) => boolean)
|
263 | | undefined;
|
264 | filename?: string | ((fileData: any) => string) | undefined;
|
265 | banner?:
|
266 | | string
|
267 | | boolean
|
268 | | ((commentsFile: string) => string)
|
269 | | undefined;
|
270 | }
|
271 | | undefined
|
272 | ) => Promise<{
|
273 | code: string;
|
274 | map?: import("@jridgewell/trace-mapping").SourceMapInput | undefined;
|
275 | errors?: (string | Error)[] | undefined;
|
276 | warnings?: (string | Error)[] | undefined;
|
277 | extractedComments?: string[] | undefined;
|
278 | }>;
|
279 | ```
|
280 |
|
281 | Default: `TerserPlugin.terserMinify`
|
282 |
|
283 | Allows you to override default minify function.
|
284 | By default plugin uses [terser](https://github.com/terser/terser) package.
|
285 | Useful for using and testing unpublished versions or forks.
|
286 |
|
287 | > **Warning**
|
288 | >
|
289 | > **Always use `require` inside `minify` function when `parallel` option enabled**.
|
290 |
|
291 | **webpack.config.js**
|
292 |
|
293 | ```js
|
294 | // Can be async
|
295 | const minify = (input, sourceMap, minimizerOptions, extractsComments) => {
|
296 | // The `minimizerOptions` option contains option from the `terserOptions` option
|
297 | // You can use `minimizerOptions.myCustomOption`
|
298 |
|
299 | // Custom logic for extract comments
|
300 | const { map, code } = require("uglify-module") // Or require('./path/to/uglify-module')
|
301 | .minify(input, {
|
302 | /* Your options for minification */
|
303 | });
|
304 |
|
305 | return { map, code, warnings: [], errors: [], extractedComments: [] };
|
306 | };
|
307 |
|
308 | // Used to regenerate `fullhash`/`chunkhash` between different implementation
|
309 | // 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
|
310 | // to avoid this you can provide version of your custom minimizer
|
311 | // You don't need if you use only `contenthash`
|
312 | minify.getMinimizerVersion = () => {
|
313 | let packageJson;
|
314 |
|
315 | try {
|
316 | // eslint-disable-next-line global-require, import/no-extraneous-dependencies
|
317 | packageJson = require("uglify-module/package.json");
|
318 | } catch (error) {
|
319 | // Ignore
|
320 | }
|
321 |
|
322 | return packageJson && packageJson.version;
|
323 | };
|
324 |
|
325 | module.exports = {
|
326 | optimization: {
|
327 | minimize: true,
|
328 | minimizer: [
|
329 | new TerserPlugin({
|
330 | terserOptions: {
|
331 | myCustomOption: true,
|
332 | },
|
333 | minify,
|
334 | }),
|
335 | ],
|
336 | },
|
337 | };
|
338 | ```
|
339 |
|
340 | ### `terserOptions`
|
341 |
|
342 | Type:
|
343 |
|
344 | ```ts
|
345 | type terserOptions = {
|
346 | compress?: boolean | CompressOptions;
|
347 | ecma?: ECMA;
|
348 | enclose?: boolean | string;
|
349 | ie8?: boolean;
|
350 | keep_classnames?: boolean | RegExp;
|
351 | keep_fnames?: boolean | RegExp;
|
352 | mangle?: boolean | MangleOptions;
|
353 | module?: boolean;
|
354 | nameCache?: object;
|
355 | format?: FormatOptions;
|
356 | /** @deprecated */
|
357 | output?: FormatOptions;
|
358 | parse?: ParseOptions;
|
359 | safari10?: boolean;
|
360 | sourceMap?: boolean | SourceMapOptions;
|
361 | toplevel?: boolean;
|
362 | };
|
363 | ```
|
364 |
|
365 | Default: [default](https://github.com/terser/terser#minify-options)
|
366 |
|
367 | Terser [options](https://github.com/terser/terser#minify-options).
|
368 |
|
369 | **webpack.config.js**
|
370 |
|
371 | ```js
|
372 | module.exports = {
|
373 | optimization: {
|
374 | minimize: true,
|
375 | minimizer: [
|
376 | new TerserPlugin({
|
377 | terserOptions: {
|
378 | ecma: undefined,
|
379 | parse: {},
|
380 | compress: {},
|
381 | mangle: true, // Note `mangle.properties` is `false` by default.
|
382 | module: false,
|
383 | // Deprecated
|
384 | output: null,
|
385 | format: null,
|
386 | toplevel: false,
|
387 | nameCache: null,
|
388 | ie8: false,
|
389 | keep_classnames: undefined,
|
390 | keep_fnames: false,
|
391 | safari10: false,
|
392 | },
|
393 | }),
|
394 | ],
|
395 | },
|
396 | };
|
397 | ```
|
398 |
|
399 | ### `extractComments`
|
400 |
|
401 | Type:
|
402 |
|
403 | ```ts
|
404 | type extractComments =
|
405 | | boolean
|
406 | | string
|
407 | | RegExp
|
408 | | ((
|
409 | astNode: any,
|
410 | comment: {
|
411 | value: string;
|
412 | type: "comment1" | "comment2" | "comment3" | "comment4";
|
413 | pos: number;
|
414 | line: number;
|
415 | col: number;
|
416 | }
|
417 | ) => boolean)
|
418 | | {
|
419 | condition?:
|
420 | | boolean
|
421 | | "all"
|
422 | | "some"
|
423 | | RegExp
|
424 | | ((
|
425 | astNode: any,
|
426 | comment: {
|
427 | value: string;
|
428 | type: "comment1" | "comment2" | "comment3" | "comment4";
|
429 | pos: number;
|
430 | line: number;
|
431 | col: number;
|
432 | }
|
433 | ) => boolean)
|
434 | | undefined;
|
435 | filename?: string | ((fileData: any) => string) | undefined;
|
436 | banner?:
|
437 | | string
|
438 | | boolean
|
439 | | ((commentsFile: string) => string)
|
440 | | undefined;
|
441 | };
|
442 | ```
|
443 |
|
444 | Default: `true`
|
445 |
|
446 | Whether comments shall be extracted to a separate file, (see [details](https://github.com/webpack/webpack/commit/71933e979e51c533b432658d5e37917f9e71595a)).
|
447 | By default extract only comments using `/^\**!|@preserve|@license|@cc_on/i` regexp condition and remove remaining comments.
|
448 | If the original file is named `foo.js`, then the comments will be stored to `foo.js.LICENSE.txt`.
|
449 | 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.
|
450 |
|
451 | #### `boolean`
|
452 |
|
453 | Enable/disable extracting comments.
|
454 |
|
455 | **webpack.config.js**
|
456 |
|
457 | ```js
|
458 | module.exports = {
|
459 | optimization: {
|
460 | minimize: true,
|
461 | minimizer: [
|
462 | new TerserPlugin({
|
463 | extractComments: true,
|
464 | }),
|
465 | ],
|
466 | },
|
467 | };
|
468 | ```
|
469 |
|
470 | #### `string`
|
471 |
|
472 | Extract `all` or `some` (use `/^\**!|@preserve|@license|@cc_on/i` RegExp) comments.
|
473 |
|
474 | **webpack.config.js**
|
475 |
|
476 | ```js
|
477 | module.exports = {
|
478 | optimization: {
|
479 | minimize: true,
|
480 | minimizer: [
|
481 | new TerserPlugin({
|
482 | extractComments: "all",
|
483 | }),
|
484 | ],
|
485 | },
|
486 | };
|
487 | ```
|
488 |
|
489 | #### `RegExp`
|
490 |
|
491 | All comments that match the given expression will be extracted to the separate file.
|
492 |
|
493 | **webpack.config.js**
|
494 |
|
495 | ```js
|
496 | module.exports = {
|
497 | optimization: {
|
498 | minimize: true,
|
499 | minimizer: [
|
500 | new TerserPlugin({
|
501 | extractComments: /@extract/i,
|
502 | }),
|
503 | ],
|
504 | },
|
505 | };
|
506 | ```
|
507 |
|
508 | #### `function`
|
509 |
|
510 | All comments that match the given expression will be extracted to the separate file.
|
511 |
|
512 | **webpack.config.js**
|
513 |
|
514 | ```js
|
515 | module.exports = {
|
516 | optimization: {
|
517 | minimize: true,
|
518 | minimizer: [
|
519 | new TerserPlugin({
|
520 | extractComments: (astNode, comment) => {
|
521 | if (/@extract/i.test(comment.value)) {
|
522 | return true;
|
523 | }
|
524 |
|
525 | return false;
|
526 | },
|
527 | }),
|
528 | ],
|
529 | },
|
530 | };
|
531 | ```
|
532 |
|
533 | #### `object`
|
534 |
|
535 | Allow to customize condition for extract comments, specify extracted file name and banner.
|
536 |
|
537 | **webpack.config.js**
|
538 |
|
539 | ```js
|
540 | module.exports = {
|
541 | optimization: {
|
542 | minimize: true,
|
543 | minimizer: [
|
544 | new TerserPlugin({
|
545 | extractComments: {
|
546 | condition: /^\**!|@preserve|@license|@cc_on/i,
|
547 | filename: (fileData) => {
|
548 | // The "fileData" argument contains object with "filename", "basename", "query" and "hash"
|
549 | return `${fileData.filename}.LICENSE.txt${fileData.query}`;
|
550 | },
|
551 | banner: (licenseFile) => {
|
552 | return `License information can be found in ${licenseFile}`;
|
553 | },
|
554 | },
|
555 | }),
|
556 | ],
|
557 | },
|
558 | };
|
559 | ```
|
560 |
|
561 | ##### `condition`
|
562 |
|
563 | Type:
|
564 |
|
565 | ```ts
|
566 | type condition =
|
567 | | boolean
|
568 | | "all"
|
569 | | "some"
|
570 | | RegExp
|
571 | | ((
|
572 | astNode: any,
|
573 | comment: {
|
574 | value: string;
|
575 | type: "comment1" | "comment2" | "comment3" | "comment4";
|
576 | pos: number;
|
577 | line: number;
|
578 | col: number;
|
579 | }
|
580 | ) => boolean)
|
581 | | undefined;
|
582 | ```
|
583 |
|
584 | Condition what comments you need extract.
|
585 |
|
586 | **webpack.config.js**
|
587 |
|
588 | ```js
|
589 | module.exports = {
|
590 | optimization: {
|
591 | minimize: true,
|
592 | minimizer: [
|
593 | new TerserPlugin({
|
594 | extractComments: {
|
595 | condition: "some",
|
596 | filename: (fileData) => {
|
597 | // The "fileData" argument contains object with "filename", "basename", "query" and "hash"
|
598 | return `${fileData.filename}.LICENSE.txt${fileData.query}`;
|
599 | },
|
600 | banner: (licenseFile) => {
|
601 | return `License information can be found in ${licenseFile}`;
|
602 | },
|
603 | },
|
604 | }),
|
605 | ],
|
606 | },
|
607 | };
|
608 | ```
|
609 |
|
610 | ##### `filename`
|
611 |
|
612 | Type:
|
613 |
|
614 | ```ts
|
615 | type filename = string | ((fileData: any) => string) | undefined;
|
616 | ```
|
617 |
|
618 | Default: `[file].LICENSE.txt[query]`
|
619 |
|
620 | Available placeholders: `[file]`, `[query]` and `[filebase]` (`[base]` for webpack 5).
|
621 |
|
622 | The file where the extracted comments will be stored.
|
623 | Default is to append the suffix `.LICENSE.txt` to the original filename.
|
624 |
|
625 | > **Warning**
|
626 | >
|
627 | > We highly recommend using the `txt` extension. Using `js`/`cjs`/`mjs` extensions may conflict with existing assets which leads to broken code.
|
628 |
|
629 | **webpack.config.js**
|
630 |
|
631 | ```js
|
632 | module.exports = {
|
633 | optimization: {
|
634 | minimize: true,
|
635 | minimizer: [
|
636 | new TerserPlugin({
|
637 | extractComments: {
|
638 | condition: /^\**!|@preserve|@license|@cc_on/i,
|
639 | filename: "extracted-comments.js",
|
640 | banner: (licenseFile) => {
|
641 | return `License information can be found in ${licenseFile}`;
|
642 | },
|
643 | },
|
644 | }),
|
645 | ],
|
646 | },
|
647 | };
|
648 | ```
|
649 |
|
650 | ##### `banner`
|
651 |
|
652 | Type:
|
653 |
|
654 | ```ts
|
655 | type banner = string | boolean | ((commentsFile: string) => string) | undefined;
|
656 | ```
|
657 |
|
658 | Default: `/*! For license information please see ${commentsFile} */`
|
659 |
|
660 | The banner text that points to the extracted file and will be added on top of the original file.
|
661 | 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.
|
662 | Will be wrapped into comment.
|
663 |
|
664 | **webpack.config.js**
|
665 |
|
666 | ```js
|
667 | module.exports = {
|
668 | optimization: {
|
669 | minimize: true,
|
670 | minimizer: [
|
671 | new TerserPlugin({
|
672 | extractComments: {
|
673 | condition: true,
|
674 | filename: (fileData) => {
|
675 | // The "fileData" argument contains object with "filename", "basename", "query" and "hash"
|
676 | return `${fileData.filename}.LICENSE.txt${fileData.query}`;
|
677 | },
|
678 | banner: (commentsFile) => {
|
679 | return `My custom banner about license information ${commentsFile}`;
|
680 | },
|
681 | },
|
682 | }),
|
683 | ],
|
684 | },
|
685 | };
|
686 | ```
|
687 |
|
688 | ## Examples
|
689 |
|
690 | ### Preserve Comments
|
691 |
|
692 | Extract all legal comments (i.e. `/^\**!|@preserve|@license|@cc_on/i`) and preserve `/@license/i` comments.
|
693 |
|
694 | **webpack.config.js**
|
695 |
|
696 | ```js
|
697 | module.exports = {
|
698 | optimization: {
|
699 | minimize: true,
|
700 | minimizer: [
|
701 | new TerserPlugin({
|
702 | terserOptions: {
|
703 | format: {
|
704 | comments: /@license/i,
|
705 | },
|
706 | },
|
707 | extractComments: true,
|
708 | }),
|
709 | ],
|
710 | },
|
711 | };
|
712 | ```
|
713 |
|
714 | ### Remove Comments
|
715 |
|
716 | If you avoid building with comments, use this config:
|
717 |
|
718 | **webpack.config.js**
|
719 |
|
720 | ```js
|
721 | module.exports = {
|
722 | optimization: {
|
723 | minimize: true,
|
724 | minimizer: [
|
725 | new TerserPlugin({
|
726 | terserOptions: {
|
727 | format: {
|
728 | comments: false,
|
729 | },
|
730 | },
|
731 | extractComments: false,
|
732 | }),
|
733 | ],
|
734 | },
|
735 | };
|
736 | ```
|
737 |
|
738 | ### [`uglify-js`](https://github.com/mishoo/UglifyJS)
|
739 |
|
740 | [`UglifyJS`](https://github.com/mishoo/UglifyJS) is a JavaScript parser, minifier, compressor and beautifier toolkit.
|
741 |
|
742 | **webpack.config.js**
|
743 |
|
744 | ```js
|
745 | module.exports = {
|
746 | optimization: {
|
747 | minimize: true,
|
748 | minimizer: [
|
749 | new TerserPlugin({
|
750 | minify: TerserPlugin.uglifyJsMinify,
|
751 | // `terserOptions` options will be passed to `uglify-js`
|
752 | // Link to options - https://github.com/mishoo/UglifyJS#minify-options
|
753 | terserOptions: {},
|
754 | }),
|
755 | ],
|
756 | },
|
757 | };
|
758 | ```
|
759 |
|
760 | ### [`swc`](https://github.com/swc-project/swc)
|
761 |
|
762 | [`swc`](https://github.com/swc-project/swc) is a super-fast compiler written in rust; producing widely-supported javascript from modern standards and typescript.
|
763 |
|
764 | > **Warning**
|
765 | >
|
766 | > the `extractComments` option is not supported and all comments will be removed by default, it will be fixed in future
|
767 |
|
768 | **webpack.config.js**
|
769 |
|
770 | ```js
|
771 | module.exports = {
|
772 | optimization: {
|
773 | minimize: true,
|
774 | minimizer: [
|
775 | new TerserPlugin({
|
776 | minify: TerserPlugin.swcMinify,
|
777 | // `terserOptions` options will be passed to `swc` (`@swc/core`)
|
778 | // Link to options - https://swc.rs/docs/config-js-minify
|
779 | terserOptions: {},
|
780 | }),
|
781 | ],
|
782 | },
|
783 | };
|
784 | ```
|
785 |
|
786 | ### [`esbuild`](https://github.com/evanw/esbuild)
|
787 |
|
788 | [`esbuild`](https://github.com/evanw/esbuild) is an extremely fast JavaScript bundler and minifier.
|
789 |
|
790 | > **Warning**
|
791 | >
|
792 | > the `extractComments` option is not supported and all legal comments (i.e. copyright, licenses and etc) will be preserved
|
793 |
|
794 | **webpack.config.js**
|
795 |
|
796 | ```js
|
797 | module.exports = {
|
798 | optimization: {
|
799 | minimize: true,
|
800 | minimizer: [
|
801 | new TerserPlugin({
|
802 | minify: TerserPlugin.esbuildMinify,
|
803 | // `terserOptions` options will be passed to `esbuild`
|
804 | // Link to options - https://esbuild.github.io/api/#minify
|
805 | // 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:
|
806 | // terserOptions: {
|
807 | // minify: false,
|
808 | // minifyWhitespace: true,
|
809 | // minifyIdentifiers: false,
|
810 | // minifySyntax: true,
|
811 | // },
|
812 | terserOptions: {},
|
813 | }),
|
814 | ],
|
815 | },
|
816 | };
|
817 | ```
|
818 |
|
819 | ### Custom Minify Function
|
820 |
|
821 | Override default minify function - use `uglify-js` for minification.
|
822 |
|
823 | **webpack.config.js**
|
824 |
|
825 | ```js
|
826 | module.exports = {
|
827 | optimization: {
|
828 | minimize: true,
|
829 | minimizer: [
|
830 | new TerserPlugin({
|
831 | minify: (file, sourceMap) => {
|
832 | // https://github.com/mishoo/UglifyJS2#minify-options
|
833 | const uglifyJsOptions = {
|
834 | /* your `uglify-js` package options */
|
835 | };
|
836 |
|
837 | if (sourceMap) {
|
838 | uglifyJsOptions.sourceMap = {
|
839 | content: sourceMap,
|
840 | };
|
841 | }
|
842 |
|
843 | return require("uglify-js").minify(file, uglifyJsOptions);
|
844 | },
|
845 | }),
|
846 | ],
|
847 | },
|
848 | };
|
849 | ```
|
850 |
|
851 | ### Typescript
|
852 |
|
853 | With default terser minify function:
|
854 |
|
855 | ```ts
|
856 | module.exports = {
|
857 | optimization: {
|
858 | minimize: true,
|
859 | minimizer: [
|
860 | new TerserPlugin({
|
861 | terserOptions: {
|
862 | compress: true,
|
863 | },
|
864 | }),
|
865 | ],
|
866 | },
|
867 | };
|
868 | ```
|
869 |
|
870 | With built-in minify functions:
|
871 |
|
872 | ```ts
|
873 | import type { JsMinifyOptions as SwcOptions } from "@swc/core";
|
874 | import type { MinifyOptions as UglifyJSOptions } from "uglify-js";
|
875 | import type { TransformOptions as EsbuildOptions } from "esbuild";
|
876 | import type { MinifyOptions as TerserOptions } from "terser";
|
877 |
|
878 | module.exports = {
|
879 | optimization: {
|
880 | minimize: true,
|
881 | minimizer: [
|
882 | new TerserPlugin<SwcOptions>({
|
883 | minify: TerserPlugin.swcMinify,
|
884 | terserOptions: {
|
885 | // `swc` options
|
886 | },
|
887 | }),
|
888 | new TerserPlugin<UglifyJSOptions>({
|
889 | minify: TerserPlugin.uglifyJsMinify,
|
890 | terserOptions: {
|
891 | // `uglif-js` options
|
892 | },
|
893 | }),
|
894 | new TerserPlugin<EsbuildOptions>({
|
895 | minify: TerserPlugin.esbuildMinify,
|
896 | terserOptions: {
|
897 | // `esbuild` options
|
898 | },
|
899 | }),
|
900 |
|
901 | // Alternative usage:
|
902 | new TerserPlugin<TerserOptions>({
|
903 | minify: TerserPlugin.terserMinify,
|
904 | terserOptions: {
|
905 | // `terser` options
|
906 | },
|
907 | }),
|
908 | ],
|
909 | },
|
910 | };
|
911 | ```
|
912 |
|
913 | ## Contributing
|
914 |
|
915 | Please take a moment to read our contributing guidelines if you haven't yet done so.
|
916 |
|
917 | [CONTRIBUTING](./.github/CONTRIBUTING.md)
|
918 |
|
919 | ## License
|
920 |
|
921 | [MIT](./LICENSE)
|
922 |
|
923 | [npm]: https://img.shields.io/npm/v/terser-webpack-plugin.svg
|
924 | [npm-url]: https://npmjs.com/package/terser-webpack-plugin
|
925 | [node]: https://img.shields.io/node/v/terser-webpack-plugin.svg
|
926 | [node-url]: https://nodejs.org
|
927 | [tests]: https://github.com/webpack-contrib/terser-webpack-plugin/workflows/terser-webpack-plugin/badge.svg
|
928 | [tests-url]: https://github.com/webpack-contrib/terser-webpack-plugin/actions
|
929 | [cover]: https://codecov.io/gh/webpack-contrib/terser-webpack-plugin/branch/master/graph/badge.svg
|
930 | [cover-url]: https://codecov.io/gh/webpack-contrib/terser-webpack-plugin
|
931 | [discussion]: https://img.shields.io/github/discussions/webpack/webpack
|
932 | [discussion-url]: https://github.com/webpack/webpack/discussions
|
933 | [size]: https://packagephobia.now.sh/badge?p=terser-webpack-plugin
|
934 | [size-url]: https://packagephobia.now.sh/result?p=terser-webpack-plugin
|