UNPKG

15.2 kBMarkdownView Raw
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[![deps][deps]][deps-url]
10[![tests][tests]][tests-url]
11[![cover][cover]][cover-url]
12[![chat][chat]][chat-url]
13[![size][size]][size-url]
14
15# terser-webpack-plugin
16
17This plugin uses [terser](https://github.com/terser-js/terser) to minify your JavaScript.
18
19## Requirements
20
21This module requires a minimum of Node v6.9.0 and Webpack v4.0.0.
22
23## Getting Started
24
25To begin, you'll need to install `terser-webpack-plugin`:
26
27```console
28$ npm install terser-webpack-plugin --save-dev
29```
30
31Then add the plugin to your `webpack` config. For example:
32
33**webpack.config.js**
34
35```js
36const TerserPlugin = require('terser-webpack-plugin');
37
38module.exports = {
39 optimization: {
40 minimizer: [new TerserPlugin()],
41 },
42};
43```
44
45And run `webpack` via your preferred method.
46
47## Options
48
49### `test`
50
51Type: `String|RegExp|Array<String|RegExp>`
52Default: `/\.m?js(\?.*)?$/i`
53
54Test to match files against.
55
56**webpack.config.js**
57
58```js
59module.exports = {
60 optimization: {
61 minimizer: [
62 new TerserPlugin({
63 test: /\.js(\?.*)?$/i,
64 }),
65 ],
66 },
67};
68```
69
70### `include`
71
72Type: `String|RegExp|Array<String|RegExp>`
73Default: `undefined`
74
75Files to include.
76
77**webpack.config.js**
78
79```js
80module.exports = {
81 optimization: {
82 minimizer: [
83 new TerserPlugin({
84 include: /\/includes/,
85 }),
86 ],
87 },
88};
89```
90
91### `exclude`
92
93Type: `String|RegExp|Array<String|RegExp>`
94Default: `undefined`
95
96Files to exclude.
97
98**webpack.config.js**
99
100```js
101module.exports = {
102 optimization: {
103 minimizer: [
104 new TerserPlugin({
105 exclude: /\/excludes/,
106 }),
107 ],
108 },
109};
110```
111
112### `chunkFilter`
113
114Type: `Function<(chunk) -> boolean>`
115Default: `() => true`
116
117Allowing to filter which chunks should be uglified (by default all chunks are uglified).
118Return `true` to uglify the chunk, `false` otherwise.
119
120**webpack.config.js**
121
122```js
123module.exports = {
124 optimization: {
125 minimizer: [
126 new TerserPlugin({
127 chunkFilter: (chunk) => {
128 // Exclude uglification for the `vendor` chunk
129 if (chunk.name === 'vendor') {
130 return false;
131 }
132
133 return true;
134 },
135 }),
136 ],
137 },
138};
139```
140
141### `cache`
142
143Type: `Boolean|String`
144Default: `false`
145
146Enable file caching.
147Default path to cache directory: `node_modules/.cache/terser-webpack-plugin`.
148
149> ℹ️ If you use your own `minify` function please read the `minify` section for cache invalidation correctly.
150
151#### `Boolean`
152
153Enable/disable file caching.
154
155**webpack.config.js**
156
157```js
158module.exports = {
159 optimization: {
160 minimizer: [
161 new TerserPlugin({
162 cache: true,
163 }),
164 ],
165 },
166};
167```
168
169#### `String`
170
171Enable file caching and set path to cache directory.
172
173**webpack.config.js**
174
175```js
176module.exports = {
177 optimization: {
178 minimizer: [
179 new TerserPlugin({
180 cache: 'path/to/cache',
181 }),
182 ],
183 },
184};
185```
186
187### `cacheKeys`
188
189Type: `Function<(defaultCacheKeys, file) -> Object>`
190Default: `defaultCacheKeys => defaultCacheKeys`
191
192Allows you to override default cache keys.
193
194Default cache keys:
195
196```js
197({
198 terser: require('terser/package.json').version, // terser version
199 'terser-webpack-plugin': require('../package.json').version, // plugin version
200 'terser-webpack-plugin-options': this.options, // plugin options
201 path: compiler.outputPath ? `${compiler.outputPath}/${file}` : file, // asset path
202 hash: crypto
203 .createHash('md4')
204 .update(input)
205 .digest('hex'), // source file hash
206});
207```
208
209**webpack.config.js**
210
211```js
212module.exports = {
213 optimization: {
214 minimizer: [
215 new TerserPlugin({
216 cache: true,
217 cacheKeys: (defaultCacheKeys, file) => {
218 defaultCacheKeys.myCacheKey = 'myCacheKeyValue';
219
220 return defaultCacheKeys;
221 },
222 }),
223 ],
224 },
225};
226```
227
228### `parallel`
229
230Type: `Boolean|Number`
231Default: `false`
232
233Use multi-process parallel running to improve the build speed.
234Default number of concurrent runs: `os.cpus().length - 1`.
235
236> ℹ️ Parallelization can speedup your build significantly and is therefore **highly recommended**.
237
238#### `Boolean`
239
240Enable/disable multi-process parallel running.
241
242**webpack.config.js**
243
244```js
245module.exports = {
246 optimization: {
247 minimizer: [
248 new TerserPlugin({
249 parallel: true,
250 }),
251 ],
252 },
253};
254```
255
256#### `Number`
257
258Enable multi-process parallel running and set number of concurrent runs.
259
260**webpack.config.js**
261
262```js
263module.exports = {
264 optimization: {
265 minimizer: [
266 new TerserPlugin({
267 parallel: 4,
268 }),
269 ],
270 },
271};
272```
273
274### `sourceMap`
275
276Type: `Boolean`
277Default: `false`
278
279Use source maps to map error message locations to modules (this slows down the compilation).
280If you use your own `minify` function please read the `minify` section for handling source maps correctly.
281
282> ⚠️ **`cheap-source-map` options don't work with this plugin**.
283
284**webpack.config.js**
285
286```js
287module.exports = {
288 optimization: {
289 minimizer: [
290 new TerserPlugin({
291 sourceMap: true,
292 }),
293 ],
294 },
295};
296```
297
298### `minify`
299
300Type: `Function`
301Default: `undefined`
302
303Allows you to override default minify function.
304By default plugin uses [terser](https://github.com/terser-js/terser) package.
305Useful for using and testing unpublished versions or forks.
306
307> ⚠️ **Always use `require` inside `minify` function when `parallel` option enabled**.
308
309**webpack.config.js**
310
311```js
312module.exports = {
313 optimization: {
314 minimizer: [
315 new TerserPlugin({
316 minify: (file, sourceMap) => {
317 const extractedComments = [];
318
319 // Custom logic for extract comments
320
321 const { error, map, code, warnings } = require('uglify-module') // Or require('./path/to/uglify-module')
322 .minify(file, {
323 /* Your options for minification */
324 });
325
326 return { error, map, code, warnings, extractedComments };
327 },
328 }),
329 ],
330 },
331};
332```
333
334### `terserOptions`
335
336Type: `Object`
337Default: [default](https://github.com/terser-js/terser#minify-options)
338
339Terser minify [options](https://github.com/terser-js/terser#minify-options).
340
341**webpack.config.js**
342
343```js
344module.exports = {
345 optimization: {
346 minimizer: [
347 new TerserPlugin({
348 terserOptions: {
349 ecma: undefined,
350 warnings: false,
351 parse: {},
352 compress: {},
353 mangle: true, // Note `mangle.properties` is `false` by default.
354 module: false,
355 output: null,
356 toplevel: false,
357 nameCache: null,
358 ie8: false,
359 keep_classnames: undefined,
360 keep_fnames: false,
361 safari10: false,
362 },
363 }),
364 ],
365 },
366};
367```
368
369### `extractComments`
370
371Type: `Boolean|String|RegExp|Function<(node, comment) -> Boolean|Object>|Object`
372Default: `false`
373
374Whether comments shall be extracted to a separate file, (see [details](https://github.com/webpack/webpack/commit/71933e979e51c533b432658d5e37917f9e71595a)).
375By default extract only comments using `/^\**!|@preserve|@license|@cc_on/i` regexp condition and remove remaining comments.
376If the original file is named `foo.js`, then the comments will be stored to `foo.js.LICENSE`.
377The `terserOptions.output.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.
378
379#### `Boolean`
380
381Enable/disable extracting comments.
382
383**webpack.config.js**
384
385```js
386module.exports = {
387 optimization: {
388 minimizer: [
389 new TerserPlugin({
390 extractComments: true,
391 }),
392 ],
393 },
394};
395```
396
397#### `String`
398
399Extract `all` or `some` (use `/^\**!|@preserve|@license|@cc_on/i` RegExp) comments.
400
401**webpack.config.js**
402
403```js
404module.exports = {
405 optimization: {
406 minimizer: [
407 new TerserPlugin({
408 extractComments: 'all',
409 }),
410 ],
411 },
412};
413```
414
415#### `RegExp`
416
417All comments that match the given expression will be extracted to the separate file.
418
419**webpack.config.js**
420
421```js
422module.exports = {
423 optimization: {
424 minimizer: [
425 new TerserPlugin({
426 extractComments: /@extract/i,
427 }),
428 ],
429 },
430};
431```
432
433#### `Function<(node, comment) -> Boolean>`
434
435All comments that match the given expression will be extracted to the separate file.
436
437**webpack.config.js**
438
439```js
440module.exports = {
441 optimization: {
442 minimizer: [
443 new TerserPlugin({
444 extractComments: (astNode, comment) => {
445 if (/@extract/i.test(comment.value)) {
446 return true;
447 }
448
449 return false;
450 },
451 }),
452 ],
453 },
454};
455```
456
457#### `Object`
458
459Allow to customize condition for extract comments, specify extracted file name and banner.
460
461**webpack.config.js**
462
463```js
464module.exports = {
465 optimization: {
466 minimizer: [
467 new TerserPlugin({
468 extractComments: {
469 condition: /^\**!|@preserve|@license|@cc_on/i,
470 filename: (file) => {
471 return `${file}.LICENSE`;
472 },
473 banner: (licenseFile) => {
474 return `License information can be found in ${licenseFile}`;
475 },
476 },
477 }),
478 ],
479 },
480};
481```
482
483##### `condition`
484
485Type: `Boolean|String|RegExp|Function<(node, comment) -> Boolean|Object>`
486
487Condition what comments you need extract.
488
489**webpack.config.js**
490
491```js
492module.exports = {
493 optimization: {
494 minimizer: [
495 new TerserPlugin({
496 extractComments: {
497 condition: 'some',
498 filename: (file) => {
499 return `${file}.LICENSE`;
500 },
501 banner: (licenseFile) => {
502 return `License information can be found in ${licenseFile}`;
503 },
504 },
505 }),
506 ],
507 },
508};
509```
510
511##### `filename`
512
513Type: `String|Function<(string) -> String>`
514Default: `${file}.LICENSE`
515
516The file where the extracted comments will be stored.
517Default is to append the suffix `.LICENSE` to the original filename.
518
519**webpack.config.js**
520
521```js
522module.exports = {
523 optimization: {
524 minimizer: [
525 new TerserPlugin({
526 extractComments: {
527 condition: /^\**!|@preserve|@license|@cc_on/i,
528 filename: 'extracted-comments.js',
529 banner: (licenseFile) => {
530 return `License information can be found in ${licenseFile}`;
531 },
532 },
533 }),
534 ],
535 },
536};
537```
538
539##### `banner`
540
541Type: `Boolean|String|Function<(string) -> String>`
542Default: `/*! For license information please see ${commentsFile} */`
543
544The banner text that points to the extracted file and will be added on top of the original file.
545Can be `false` (no banner), a `String`, or a `Function<(string) -> String>` that will be called with the filename where extracted comments have been stored.
546Will be wrapped into comment.
547
548**webpack.config.js**
549
550```js
551module.exports = {
552 optimization: {
553 minimizer: [
554 new TerserPlugin({
555 extractComments: {
556 condition: true,
557 filename: (file) => {
558 return `${file}.LICENSE`;
559 },
560 banner: (commentsFile) => {
561 return `My custom banner about license information ${commentsFile}`;
562 },
563 },
564 }),
565 ],
566 },
567};
568```
569
570### `warningsFilter`
571
572Type: `Function<(warning, source) -> Boolean>`
573Default: `() => true`
574
575Allow to filter [terser](https://github.com/terser-js/terser) warnings.
576Return `true` to keep the warning, `false` otherwise.
577
578**webpack.config.js**
579
580```js
581module.exports = {
582 optimization: {
583 minimizer: [
584 new TerserPlugin({
585 warningsFilter: (warning, source) => {
586 if (/Dropping unreachable code/i.test(warning)) {
587 return true;
588 }
589
590 if (/filename\.js/i.test(source)) {
591 return true;
592 }
593
594 return false;
595 },
596 }),
597 ],
598 },
599};
600```
601
602## Examples
603
604### Cache And Parallel
605
606Enable cache and multi-process parallel running.
607
608**webpack.config.js**
609
610```js
611module.exports = {
612 optimization: {
613 minimizer: [
614 new TerserPlugin({
615 cache: true,
616 parallel: true,
617 }),
618 ],
619 },
620};
621```
622
623### Preserve Comments
624
625Extract all legal comments (i.e. `/^\**!|@preserve|@license|@cc_on/i`) and preserve `/@license/i` comments.
626
627**webpack.config.js**
628
629```js
630module.exports = {
631 optimization: {
632 minimizer: [
633 new TerserPlugin({
634 terserOptions: {
635 output: {
636 comments: /@license/i,
637 },
638 },
639 extractComments: true,
640 }),
641 ],
642 },
643};
644```
645
646### Remove Comments
647
648If you avoid building with comments, set **terserOptions.output.comments** to **false** as in this config:
649
650**webpack.config.js**
651
652```js
653module.exports = {
654 optimization: {
655 minimizer: [
656 new TerserPlugin({
657 terserOptions: {
658 output: {
659 comments: false,
660 },
661 },
662 }),
663 ],
664 },
665};
666```
667
668### Custom Minify Function
669
670Override default minify function - use `uglify-js` for minification.
671
672**webpack.config.js**
673
674```js
675module.exports = {
676 optimization: {
677 minimizer: [
678 new TerserPlugin({
679 // Uncomment lines below for cache invalidation correctly
680 // cache: true,
681 // cacheKeys: (defaultCacheKeys) => {
682 // delete defaultCacheKeys.terser;
683 //
684 // return Object.assign(
685 // {},
686 // defaultCacheKeys,
687 // { 'uglify-js': require('uglify-js/package.json').version },
688 // );
689 // },
690 minify: (file, sourceMap) => {
691 // https://github.com/mishoo/UglifyJS2#minify-options
692 const uglifyJsOptions = {
693 /* your `uglify-js` package options */
694 };
695
696 if (sourceMap) {
697 uglifyJsOptions.sourceMap = {
698 content: sourceMap,
699 };
700 }
701
702 return require('uglify-js').minify(file, uglifyJsOptions);
703 },
704 }),
705 ],
706 },
707};
708```
709
710## Contributing
711
712Please take a moment to read our contributing guidelines if you haven't yet done so.
713
714[CONTRIBUTING](./.github/CONTRIBUTING.md)
715
716## License
717
718[MIT](./LICENSE)
719
720[npm]: https://img.shields.io/npm/v/terser-webpack-plugin.svg
721[npm-url]: https://npmjs.com/package/terser-webpack-plugin
722[node]: https://img.shields.io/node/v/terser-webpack-plugin.svg
723[node-url]: https://nodejs.org
724[deps]: https://david-dm.org/webpack-contrib/terser-webpack-plugin.svg
725[deps-url]: https://david-dm.org/webpack-contrib/terser-webpack-plugin
726[tests]: https://img.shields.io/circleci/project/github/webpack-contrib/terser-webpack-plugin.svg
727[tests-url]: https://circleci.com/gh/webpack-contrib/terser-webpack-plugin
728[cover]: https://codecov.io/gh/webpack-contrib/terser-webpack-plugin/branch/master/graph/badge.svg
729[cover-url]: https://codecov.io/gh/webpack-contrib/terser-webpack-plugin
730[chat]: https://img.shields.io/badge/gitter-webpack%2Fwebpack-brightgreen.svg
731[chat-url]: https://gitter.im/webpack/webpack
732[size]: https://packagephobia.now.sh/badge?p=terser-webpack-plugin
733[size-url]: https://packagephobia.now.sh/result?p=terser-webpack-plugin