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