document ECMAScript quirks (#5148)
[UglifyJS.git] / README.md
1 UglifyJS 3
2 ==========
3
4 UglifyJS is a JavaScript parser, minifier, compressor and beautifier toolkit.
5
6 #### Note:
7 - `uglify-js` supports JavaScript and most language features in ECMAScript.
8 - For more exotic parts of ECMAScript, process your source file with transpilers
9   like [Babel](https://babeljs.io/) before passing onto `uglify-js`.
10 - `uglify-js@3` has a simplified [API](#api-reference) and [CLI](#command-line-usage)
11   that is not backwards compatible with [`uglify-js@2`](https://github.com/mishoo/UglifyJS/tree/v2.x).
12
13 Install
14 -------
15
16 First make sure you have installed the latest version of [node.js](http://nodejs.org/)
17 (You may need to restart your computer after this step).
18
19 From NPM for use as a command line app:
20
21     npm install uglify-js -g
22
23 From NPM for programmatic use:
24
25     npm install uglify-js
26
27 # Command line usage
28
29     uglifyjs [input files] [options]
30
31 UglifyJS can take multiple input files.  It's recommended that you pass the
32 input files first, then pass the options.  UglifyJS will parse input files
33 in sequence and apply any compression options.  The files are parsed in the
34 same global scope, that is, a reference from a file to some
35 variable/function declared in another file will be matched properly.
36
37 If no input file is specified, UglifyJS will read from STDIN.
38
39 If you wish to pass your options before the input files, separate the two with
40 a double dash to prevent input files being used as option arguments:
41
42     uglifyjs --compress --mangle -- input.js
43
44 ### Command line options
45
46 ```
47     -h, --help                  Print usage information.
48                                 `--help options` for details on available options.
49     -V, --version               Print version number.
50     -p, --parse <options>       Specify parser options:
51                                 `acorn`  Use Acorn for parsing.
52                                 `bare_returns`  Allow return outside of functions.
53                                                 Useful when minifying CommonJS
54                                                 modules and Userscripts that may
55                                                 be anonymous function wrapped (IIFE)
56                                                 by the .user.js engine `caller`.
57                                 `expression`  Parse a single expression, rather than
58                                               a program (for parsing JSON).
59                                 `spidermonkey`  Assume input files are SpiderMonkey
60                                                 AST format (as JSON).
61     -c, --compress [options]    Enable compressor/specify compressor options:
62                                 `pure_funcs`  List of functions that can be safely
63                                               removed when their return values are
64                                               not used.
65     -m, --mangle [options]      Mangle names/specify mangler options:
66                                 `reserved`  List of names that should not be mangled.
67     --mangle-props [options]    Mangle properties/specify mangler options:
68                                 `builtins`  Mangle property names that overlaps
69                                             with standard JavaScript globals.
70                                 `debug`  Add debug prefix and suffix.
71                                 `domprops`  Mangle property names that overlaps
72                                             with DOM properties.
73                                 `keep_quoted`  Only mangle unquoted properties.
74                                 `regex`  Only mangle matched property names.
75                                 `reserved`  List of names that should not be mangled.
76     -b, --beautify [options]    Beautify output/specify output options:
77                                 `beautify`  Enabled with `--beautify` by default.
78                                 `preamble`  Preamble to prepend to the output. You
79                                             can use this to insert a comment, for
80                                             example for licensing information.
81                                             This will not be parsed, but the source
82                                             map will adjust for its presence.
83                                 `quote_style`  Quote style:
84                                                0 - auto
85                                                1 - single
86                                                2 - double
87                                                3 - original
88                                 `wrap_iife`  Wrap IIFEs in parentheses. Note: you may
89                                              want to disable `negate_iife` under
90                                              compressor options.
91     -O, --output-opts [options] Specify output options (`beautify` disabled by default).
92     -o, --output <file>         Output file path (default STDOUT). Specify `ast` or
93                                 `spidermonkey` to write UglifyJS or SpiderMonkey AST
94                                 as JSON to STDOUT respectively.
95     --annotations               Process and preserve comment annotations.
96                                 (`/*@__PURE__*/` or `/*#__PURE__*/`)
97     --no-annotations            Ignore and discard comment annotations.
98     --comments [filter]         Preserve copyright comments in the output. By
99                                 default this works like Google Closure, keeping
100                                 JSDoc-style comments that contain "@license" or
101                                 "@preserve". You can optionally pass one of the
102                                 following arguments to this flag:
103                                 - "all" to keep all comments
104                                 - a valid JS RegExp like `/foo/` or `/^!/` to
105                                 keep only matching comments.
106                                 Note that currently not *all* comments can be
107                                 kept when compression is on, because of dead
108                                 code removal or cascading statements into
109                                 sequences.
110     --config-file <file>        Read `minify()` options from JSON file.
111     -d, --define <expr>[=value] Global definitions.
112     -e, --enclose [arg[:value]] Embed everything in a big function, with configurable
113                                 argument(s) & value(s).
114     --ie                        Support non-standard Internet Explorer.
115                                 Equivalent to setting `ie: true` in `minify()`
116                                 for `compress`, `mangle` and `output` options.
117                                 By default UglifyJS will not try to be IE-proof.
118     --keep-fnames               Do not mangle/drop function names.  Useful for
119                                 code relying on Function.prototype.name.
120     --name-cache <file>         File to hold mangled name mappings.
121     --self                      Build UglifyJS as a library (implies --wrap UglifyJS)
122     --source-map [options]      Enable source map/specify source map options:
123                                 `base`  Path to compute relative paths from input files.
124                                 `content`  Input source map, useful if you're compressing
125                                            JS that was generated from some other original
126                                            code. Specify "inline" if the source map is
127                                            included within the sources.
128                                 `filename`  Filename and/or location of the output source
129                                             (sets `file` attribute in source map).
130                                 `includeSources`  Pass this flag if you want to include
131                                                   the content of source files in the
132                                                   source map as sourcesContent property.
133                                 `names` Include symbol names in the source map.
134                                 `root`  Path to the original source to be included in
135                                         the source map.
136                                 `url`  If specified, path to the source map to append in
137                                        `//# sourceMappingURL`.
138     --timings                   Display operations run time on STDERR.
139     --toplevel                  Compress and/or mangle variables in top level scope.
140     --v8                        Support non-standard Chrome & Node.js
141                                 Equivalent to setting `v8: true` in `minify()`
142                                 for `mangle` and `output` options.
143                                 By default UglifyJS will not try to be v8-proof.
144     --verbose                   Print diagnostic messages.
145     --warn                      Print warning messages.
146     --webkit                    Support non-standard Safari/Webkit.
147                                 Equivalent to setting `webkit: true` in `minify()`
148                                 for `mangle` and `output` options.
149                                 By default UglifyJS will not try to be Safari-proof.
150     --wrap <name>               Embed everything in a big function, making the
151                                 “exports” and “global” variables available. You
152                                 need to pass an argument to this option to
153                                 specify the name that your module will take
154                                 when included in, say, a browser.
155 ```
156
157 Specify `--output` (`-o`) to declare the output file.  Otherwise the output
158 goes to STDOUT.
159
160 ## CLI source map options
161
162 UglifyJS can generate a source map file, which is highly useful for
163 debugging your compressed JavaScript.  To get a source map, pass
164 `--source-map --output output.js` (source map will be written out to
165 `output.js.map`).
166
167 Additional options:
168
169 - `--source-map "filename='<NAME>'"` to specify the name of the source map. The value of
170   `filename` is only used to set `file` attribute (see [the spec][sm-spec])
171   in source map file.
172
173 - `--source-map "root='<URL>'"` to pass the URL where the original files can be found.
174
175 - `--source-map "names=false"` to omit symbol names if you want to reduce size
176   of the source map file.
177
178 - `--source-map "url='<URL>'"` to specify the URL where the source map can be found.
179   Otherwise UglifyJS assumes HTTP `X-SourceMap` is being used and will omit the
180   `//# sourceMappingURL=` directive.
181
182 For example:
183
184     uglifyjs js/file1.js js/file2.js \
185              -o foo.min.js -c -m \
186              --source-map "root='http://foo.com/src',url='foo.min.js.map'"
187
188 The above will compress and mangle `file1.js` and `file2.js`, will drop the
189 output in `foo.min.js` and the source map in `foo.min.js.map`.  The source
190 mapping will refer to `http://foo.com/src/js/file1.js` and
191 `http://foo.com/src/js/file2.js` (in fact it will list `http://foo.com/src`
192 as the source map root, and the original files as `js/file1.js` and
193 `js/file2.js`).
194
195 ### Composed source map
196
197 When you're compressing JS code that was output by a compiler such as
198 CoffeeScript, mapping to the JS code won't be too helpful.  Instead, you'd
199 like to map back to the original code (i.e. CoffeeScript).  UglifyJS has an
200 option to take an input source map.  Assuming you have a mapping from
201 CoffeeScript → compiled JS, UglifyJS can generate a map from CoffeeScript →
202 compressed JS by mapping every token in the compiled JS to its original
203 location.
204
205 To use this feature pass `--source-map "content='/path/to/input/source.map'"`
206 or `--source-map "content=inline"` if the source map is included inline with
207 the sources.
208
209 ## CLI compress options
210
211 You need to pass `--compress` (`-c`) to enable the compressor.  Optionally
212 you can pass a comma-separated list of [compress options](#compress-options).
213
214 Options are in the form `foo=bar`, or just `foo` (the latter implies
215 a boolean option that you want to set `true`; it's effectively a
216 shortcut for `foo=true`).
217
218 Example:
219
220     uglifyjs file.js -c toplevel,sequences=false
221
222 ## CLI mangle options
223
224 To enable the mangler you need to pass `--mangle` (`-m`).  The following
225 (comma-separated) options are supported:
226
227 - `eval` (default: `false`) — mangle names visible in scopes where `eval` or
228   `with` are used.
229
230 - `reserved` (default: `[]`) — when mangling is enabled but you want to
231   prevent certain names from being mangled, you can declare those names with
232   `--mangle reserved` — pass a comma-separated list of names.  For example:
233
234       uglifyjs ... -m reserved=['$','require','exports']
235
236   to prevent the `require`, `exports` and `$` names from being changed.
237
238 ### CLI mangling property names (`--mangle-props`)
239
240 **Note:** THIS WILL PROBABLY BREAK YOUR CODE.  Mangling property names
241 is a separate step, different from variable name mangling.  Pass
242 `--mangle-props` to enable it.  It will mangle all properties in the
243 input code with the exception of built in DOM properties and properties
244 in core JavaScript classes.  For example:
245
246 ```javascript
247 // example.js
248 var x = {
249     baz_: 0,
250     foo_: 1,
251     calc: function() {
252         return this.foo_ + this.baz_;
253     }
254 };
255 x.bar_ = 2;
256 x["baz_"] = 3;
257 console.log(x.calc());
258 ```
259 Mangle all properties (except for JavaScript `builtins`):
260 ```bash
261 $ uglifyjs example.js -c -m --mangle-props
262 ```
263 ```javascript
264 var x={o:0,_:1,l:function(){return this._+this.o}};x.t=2,x.o=3,console.log(x.l());
265 ```
266 Mangle all properties except for `reserved` properties:
267 ```bash
268 $ uglifyjs example.js -c -m --mangle-props reserved=[foo_,bar_]
269 ```
270 ```javascript
271 var x={o:0,foo_:1,_:function(){return this.foo_+this.o}};x.bar_=2,x.o=3,console.log(x._());
272 ```
273 Mangle all properties matching a `regex`:
274 ```bash
275 $ uglifyjs example.js -c -m --mangle-props regex=/_$/
276 ```
277 ```javascript
278 var x={o:0,_:1,calc:function(){return this._+this.o}};x.l=2,x.o=3,console.log(x.calc());
279 ```
280
281 Combining mangle properties options:
282 ```bash
283 $ uglifyjs example.js -c -m --mangle-props regex=/_$/,reserved=[bar_]
284 ```
285 ```javascript
286 var x={o:0,_:1,calc:function(){return this._+this.o}};x.bar_=2,x.o=3,console.log(x.calc());
287 ```
288
289 In order for this to be of any use, we avoid mangling standard JS names by
290 default (`--mangle-props builtins` to override).
291
292 A default exclusion file is provided in `tools/domprops.json` which should
293 cover most standard JS and DOM properties defined in various browsers.  Pass
294 `--mangle-props domprops` to disable this feature.
295
296 A regular expression can be used to define which property names should be
297 mangled.  For example, `--mangle-props regex=/^_/` will only mangle property
298 names that start with an underscore.
299
300 When you compress multiple files using this option, in order for them to
301 work together in the end we need to ensure somehow that one property gets
302 mangled to the same name in all of them.  For this, pass `--name-cache filename.json`
303 and UglifyJS will maintain these mappings in a file which can then be reused.
304 It should be initially empty.  Example:
305
306 ```bash
307 $ rm -f /tmp/cache.json  # start fresh
308 $ uglifyjs file1.js file2.js --mangle-props --name-cache /tmp/cache.json -o part1.js
309 $ uglifyjs file3.js file4.js --mangle-props --name-cache /tmp/cache.json -o part2.js
310 ```
311
312 Now, `part1.js` and `part2.js` will be consistent with each other in terms
313 of mangled property names.
314
315 Using the name cache is not necessary if you compress all your files in a
316 single call to UglifyJS.
317
318 ### Mangling unquoted names (`--mangle-props keep_quoted`)
319
320 Using quoted property name (`o["foo"]`) reserves the property name (`foo`)
321 so that it is not mangled throughout the entire script even when used in an
322 unquoted style (`o.foo`). Example:
323
324 ```javascript
325 // stuff.js
326 var o = {
327     "foo": 1,
328     bar: 3
329 };
330 o.foo += o.bar;
331 console.log(o.foo);
332 ```
333 ```bash
334 $ uglifyjs stuff.js --mangle-props keep_quoted -c -m
335 ```
336 ```javascript
337 var o={foo:1,o:3};o.foo+=o.o,console.log(o.foo);
338 ```
339
340 ### Debugging property name mangling
341
342 You can also pass `--mangle-props debug` in order to mangle property names
343 without completely obscuring them. For example the property `o.foo`
344 would mangle to `o._$foo$_` with this option. This allows property mangling
345 of a large codebase while still being able to debug the code and identify
346 where mangling is breaking things.
347
348 ```bash
349 $ uglifyjs stuff.js --mangle-props debug -c -m
350 ```
351 ```javascript
352 var o={_$foo$_:1,_$bar$_:3};o._$foo$_+=o._$bar$_,console.log(o._$foo$_);
353 ```
354
355 You can also pass a custom suffix using `--mangle-props debug=XYZ`. This would then
356 mangle `o.foo` to `o._$foo$XYZ_`. You can change this each time you compile a
357 script to identify how a property got mangled. One technique is to pass a
358 random number on every compile to simulate mangling changing with different
359 inputs (e.g. as you update the input script with new properties), and to help
360 identify mistakes like writing mangled keys to storage.
361
362
363 # API Reference
364
365 Assuming installation via NPM, you can load UglifyJS in your application
366 like this:
367 ```javascript
368 var UglifyJS = require("uglify-js");
369 ```
370
371 There is a single high level function, **`minify(code, options)`**,
372 which will perform all minification [phases](#minify-options) in a configurable
373 manner. By default `minify()` will enable the options [`compress`](#compress-options)
374 and [`mangle`](#mangle-options). Example:
375 ```javascript
376 var code = "function add(first, second) { return first + second; }";
377 var result = UglifyJS.minify(code);
378 console.log(result.error); // runtime error, or `undefined` if no error
379 console.log(result.code);  // minified output: function add(n,d){return n+d}
380 ```
381
382 You can `minify` more than one JavaScript file at a time by using an object
383 for the first argument where the keys are file names and the values are source
384 code:
385 ```javascript
386 var code = {
387     "file1.js": "function add(first, second) { return first + second; }",
388     "file2.js": "console.log(add(1 + 2, 3 + 4));"
389 };
390 var result = UglifyJS.minify(code);
391 console.log(result.code);
392 // function add(d,n){return d+n}console.log(add(3,7));
393 ```
394
395 The `toplevel` option:
396 ```javascript
397 var code = {
398     "file1.js": "function add(first, second) { return first + second; }",
399     "file2.js": "console.log(add(1 + 2, 3 + 4));"
400 };
401 var options = { toplevel: true };
402 var result = UglifyJS.minify(code, options);
403 console.log(result.code);
404 // console.log(3+7);
405 ```
406
407 The `nameCache` option:
408 ```javascript
409 var options = {
410     mangle: {
411         toplevel: true,
412     },
413     nameCache: {}
414 };
415 var result1 = UglifyJS.minify({
416     "file1.js": "function add(first, second) { return first + second; }"
417 }, options);
418 var result2 = UglifyJS.minify({
419     "file2.js": "console.log(add(1 + 2, 3 + 4));"
420 }, options);
421 console.log(result1.code);
422 // function n(n,r){return n+r}
423 console.log(result2.code);
424 // console.log(n(3,7));
425 ```
426
427 You may persist the name cache to the file system in the following way:
428 ```javascript
429 var cacheFileName = "/tmp/cache.json";
430 var options = {
431     mangle: {
432         properties: true,
433     },
434     nameCache: JSON.parse(fs.readFileSync(cacheFileName, "utf8"))
435 };
436 fs.writeFileSync("part1.js", UglifyJS.minify({
437     "file1.js": fs.readFileSync("file1.js", "utf8"),
438     "file2.js": fs.readFileSync("file2.js", "utf8")
439 }, options).code, "utf8");
440 fs.writeFileSync("part2.js", UglifyJS.minify({
441     "file3.js": fs.readFileSync("file3.js", "utf8"),
442     "file4.js": fs.readFileSync("file4.js", "utf8")
443 }, options).code, "utf8");
444 fs.writeFileSync(cacheFileName, JSON.stringify(options.nameCache), "utf8");
445 ```
446
447 An example of a combination of `minify()` options:
448 ```javascript
449 var code = {
450     "file1.js": "function add(first, second) { return first + second; }",
451     "file2.js": "console.log(add(1 + 2, 3 + 4));"
452 };
453 var options = {
454     toplevel: true,
455     compress: {
456         global_defs: {
457             "@console.log": "alert"
458         },
459         passes: 2
460     },
461     output: {
462         beautify: false,
463         preamble: "/* uglified */"
464     }
465 };
466 var result = UglifyJS.minify(code, options);
467 console.log(result.code);
468 // /* uglified */
469 // alert(10);"
470 ```
471
472 To produce warnings:
473 ```javascript
474 var code = "function f(){ var u; return 2 + 3; }";
475 var options = { warnings: true };
476 var result = UglifyJS.minify(code, options);
477 console.log(result.error);    // runtime error, `undefined` in this case
478 console.log(result.warnings); // [ 'Dropping unused variable u [0:1,18]' ]
479 console.log(result.code);     // function f(){return 5}
480 ```
481
482 An error example:
483 ```javascript
484 var result = UglifyJS.minify({"foo.js" : "if (0) else console.log(1);"});
485 console.log(JSON.stringify(result.error));
486 // {"message":"Unexpected token: keyword (else)","filename":"foo.js","line":1,"col":7,"pos":7}
487 ```
488 Note: unlike `uglify-js@2.x`, the `3.x` API does not throw errors. To
489 achieve a similar effect one could do the following:
490 ```javascript
491 var result = UglifyJS.minify(code, options);
492 if (result.error) throw result.error;
493 ```
494
495 ## Minify options
496
497 - `annotations` — pass `false` to ignore all comment annotations and elide them
498   from output. Useful when, for instance, external tools incorrectly applied
499   `/*@__PURE__*/` or `/*#__PURE__*/`. Pass `true` to both compress and retain
500   comment annotations in output to allow for further processing downstream.
501
502 - `compress` (default: `{}`) — pass `false` to skip compressing entirely.
503   Pass an object to specify custom [compress options](#compress-options).
504
505 - `ie` (default: `false`) — enable workarounds for Internet Explorer bugs.
506
507 - `keep_fnames` (default: `false`) — pass `true` to prevent discarding or mangling
508   of function names.  Useful for code relying on `Function.prototype.name`.
509
510 - `mangle` (default: `true`) — pass `false` to skip mangling names, or pass
511   an object to specify [mangle options](#mangle-options) (see below).
512
513   - `mangle.properties` (default: `false`) — a subcategory of the mangle option.
514     Pass an object to specify custom [mangle property options](#mangle-properties-options).
515
516 - `nameCache` (default: `null`) — pass an empty object `{}` or a previously
517   used `nameCache` object if you wish to cache mangled variable and
518   property names across multiple invocations of `minify()`. Note: this is
519   a read/write property. `minify()` will read the name cache state of this
520   object and update it during minification so that it may be
521   reused or externally persisted by the user.
522
523 - `output` (default: `null`) — pass an object if you wish to specify
524   additional [output options](#output-options).  The defaults are optimized
525   for best compression.
526
527 - `parse` (default: `{}`) — pass an object if you wish to specify some
528   additional [parse options](#parse-options).
529
530 - `sourceMap` (default: `false`) — pass an object if you wish to specify
531   [source map options](#source-map-options).
532
533 - `toplevel` (default: `false`) — set to `true` if you wish to enable top level
534   variable and function name mangling and to drop unused variables and functions.
535
536 - `v8` (default: `false`) — enable workarounds for Chrome & Node.js bugs.
537
538 - `warnings` (default: `false`) — pass `true` to return compressor warnings
539   in `result.warnings`. Use the value `"verbose"` for more detailed warnings.
540
541 - `webkit` (default: `false`) — enable workarounds for Safari/WebKit bugs.
542   PhantomJS users should set this option to `true`.
543
544 ## Minify options structure
545
546 ```javascript
547 {
548     parse: {
549         // parse options
550     },
551     compress: {
552         // compress options
553     },
554     mangle: {
555         // mangle options
556
557         properties: {
558             // mangle property options
559         }
560     },
561     output: {
562         // output options
563     },
564     sourceMap: {
565         // source map options
566     },
567     nameCache: null, // or specify a name cache object
568     toplevel: false,
569     warnings: false,
570 }
571 ```
572
573 ### Source map options
574
575 To generate a source map:
576 ```javascript
577 var result = UglifyJS.minify({"file1.js": "var a = function() {};"}, {
578     sourceMap: {
579         filename: "out.js",
580         url: "out.js.map"
581     }
582 });
583 console.log(result.code); // minified output
584 console.log(result.map);  // source map
585 ```
586
587 Note that the source map is not saved in a file, it's just returned in
588 `result.map`.  The value passed for `sourceMap.url` is only used to set
589 `//# sourceMappingURL=out.js.map` in `result.code`. The value of
590 `filename` is only used to set `file` attribute (see [the spec][sm-spec])
591 in source map file.
592
593 You can set option `sourceMap.url` to be `"inline"` and source map will
594 be appended to code.
595
596 You can also specify sourceRoot property to be included in source map:
597 ```javascript
598 var result = UglifyJS.minify({"file1.js": "var a = function() {};"}, {
599     sourceMap: {
600         root: "http://example.com/src",
601         url: "out.js.map"
602     }
603 });
604 ```
605
606 If you're compressing compiled JavaScript and have a source map for it, you
607 can use `sourceMap.content`:
608 ```javascript
609 var result = UglifyJS.minify({"compiled.js": "compiled code"}, {
610     sourceMap: {
611         content: "content from compiled.js.map",
612         url: "minified.js.map"
613     }
614 });
615 // same as before, it returns `code` and `map`
616 ```
617
618 If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.url`.
619
620 If you wish to reduce file size of the source map, set option `sourceMap.names`
621 to be `false` and all symbol names will be omitted.
622
623 ## Parse options
624
625 - `bare_returns` (default: `false`) — support top level `return` statements
626
627 - `html5_comments` (default: `true`)
628
629 - `shebang` (default: `true`) — support `#!command` as the first line
630
631 ## Compress options
632
633 - `annotations` (default: `true`) — Pass `false` to disable potentially dropping
634   functions marked as "pure".  A function call is marked as "pure" if a comment
635   annotation `/*@__PURE__*/` or `/*#__PURE__*/` immediately precedes the call. For
636   example: `/*@__PURE__*/foo();`
637
638 - `arguments` (default: `true`) — replace `arguments[index]` with function
639   parameter name whenever possible.
640
641 - `arrows` (default: `true`) — apply optimizations to arrow functions
642
643 - `assignments` (default: `true`) — apply optimizations to assignment expressions
644
645 - `awaits` (default: `true`) — apply optimizations to `await` expressions
646
647 - `booleans` (default: `true`) — various optimizations for boolean context,
648   for example `!!a ? b : c → a ? b : c`
649
650 - `collapse_vars` (default: `true`) — Collapse single-use non-constant variables,
651   side effects permitting.
652
653 - `comparisons` (default: `true`) — apply certain optimizations to binary nodes,
654   e.g. `!(a <= b) → a > b`, attempts to negate binary nodes, e.g.
655   `a = !b && !c && !d && !e → a=!(b||c||d||e)` etc.
656
657 - `conditionals` (default: `true`) — apply optimizations for `if`-s and conditional
658   expressions
659
660 - `dead_code` (default: `true`) — remove unreachable code
661
662 - `default_values` (default: `true`) — drop overshadowed default values
663
664 - `directives` (default: `true`) — remove redundant or non-standard directives
665
666 - `drop_console` (default: `false`) — Pass `true` to discard calls to
667   `console.*` functions. If you wish to drop a specific function call
668   such as `console.info` and/or retain side effects from function arguments
669   after dropping the function call then use `pure_funcs` instead.
670
671 - `drop_debugger` (default: `true`) — remove `debugger;` statements
672
673 - `evaluate` (default: `true`) — Evaluate expression for shorter constant
674   representation. Pass `"eager"` to always replace function calls whenever
675   possible, or a positive integer to specify an upper bound for each individual
676   evaluation in number of characters.
677
678 - `expression` (default: `false`) — Pass `true` to preserve completion values
679   from terminal statements without `return`, e.g. in bookmarklets.
680
681 - `functions` (default: `true`) — convert declarations from `var` to `function`
682   whenever possible.
683
684 - `global_defs` (default: `{}`) — see [conditional compilation](#conditional-compilation)
685
686 - `hoist_exports` (default: `true`) — hoist `export` statements to facilitate
687   various `compress` and `mangle` optimizations.
688
689 - `hoist_funs` (default: `false`) — hoist function declarations
690
691 - `hoist_props` (default: `true`) — hoist properties from constant object and
692   array literals into regular variables subject to a set of constraints. For example:
693   `var o={p:1, q:2}; f(o.p, o.q);` is converted to `f(1, 2);`. Note: `hoist_props`
694   works best with `toplevel` and `mangle` enabled, alongside with `compress` option
695   `passes` set to `2` or higher.
696
697 - `hoist_vars` (default: `false`) — hoist `var` declarations (this is `false`
698   by default because it seems to increase the size of the output in general)
699
700 - `if_return` (default: `true`) — optimizations for if/return and if/continue
701
702 - `imports` (default: `true`) — drop unreferenced import symbols when used with `unused`
703
704 - `inline` (default: `true`) — inline calls to function with simple/`return` statement:
705   - `false` — same as `0`
706   - `0` — disabled inlining
707   - `1` — inline simple functions
708   - `2` — inline functions with arguments
709   - `3` — inline functions with arguments and variables
710   - `true` — same as `3`
711
712 - `join_vars` (default: `true`) — join consecutive `var` statements
713
714 - `keep_fargs` (default: `false`) — discard unused function arguments except
715   when unsafe to do so, e.g. code which relies on `Function.prototype.length`.
716   Pass `true` to always retain function arguments.
717
718 - `keep_infinity` (default: `false`) — Pass `true` to prevent `Infinity` from
719   being compressed into `1/0`, which may cause performance issues on Chrome.
720
721 - `loops` (default: `true`) — optimizations for `do`, `while` and `for` loops
722   when we can statically determine the condition.
723
724 - `merge_vars` (default: `true`) — combine and reuse variables.
725
726 - `negate_iife` (default: `true`) — negate "Immediately-Called Function Expressions"
727   where the return value is discarded, to avoid the parens that the
728   code generator would insert.
729
730 - `objects` (default: `true`) — compact duplicate keys in object literals.
731
732 - `passes` (default: `1`) — The maximum number of times to run compress.
733   In some cases more than one pass leads to further compressed code.  Keep in
734   mind more passes will take more time.
735
736 - `properties` (default: `true`) — rewrite property access using the dot notation, for
737   example `foo["bar"] → foo.bar`
738
739 - `pure_funcs` (default: `null`) — You can pass an array of names and
740   UglifyJS will assume that those functions do not produce side
741   effects.  DANGER: will not check if the name is redefined in scope.
742   An example case here, for instance `var q = Math.floor(a/b)`.  If
743   variable `q` is not used elsewhere, UglifyJS will drop it, but will
744   still keep the `Math.floor(a/b)`, not knowing what it does.  You can
745   pass `pure_funcs: [ 'Math.floor' ]` to let it know that this
746   function won't produce any side effect, in which case the whole
747   statement would get discarded.  The current implementation adds some
748   overhead (compression will be slower). Make sure symbols under `pure_funcs`
749   are also under `mangle.reserved` to avoid mangling.
750
751 - `pure_getters` (default: `"strict"`) — If you pass `true` for
752   this, UglifyJS will assume that object property access
753   (e.g. `foo.bar` or `foo["bar"]`) doesn't have any side effects.
754   Specify `"strict"` to treat `foo.bar` as side-effect-free only when
755   `foo` is certain to not throw, i.e. not `null` or `undefined`.
756
757 - `reduce_funcs` (default: `true`) — Allows single-use functions to be
758   inlined as function expressions when permissible allowing further
759   optimization.  Enabled by default.  Option depends on `reduce_vars`
760   being enabled.  Some code runs faster in the Chrome V8 engine if this
761   option is disabled.  Does not negatively impact other major browsers.
762
763 - `reduce_vars` (default: `true`) — Improve optimization on variables assigned with and
764   used as constant values.
765
766 - `rests` (default: `true`) — apply optimizations to rest parameters
767
768 - `sequences` (default: `true`) — join consecutive simple statements using the
769   comma operator.  May be set to a positive integer to specify the maximum number
770   of consecutive comma sequences that will be generated. If this option is set to
771   `true` then the default `sequences` limit is `200`. Set option to `false` or `0`
772   to disable. The smallest `sequences` length is `2`. A `sequences` value of `1`
773   is grandfathered to be equivalent to `true` and as such means `200`. On rare
774   occasions the default sequences limit leads to very slow compress times in which
775   case a value of `20` or less is recommended.
776
777 - `side_effects` (default: `true`) — drop extraneous code which does not affect
778   outcome of runtime execution.
779
780 - `spreads` (default: `true`) — flatten spread expressions.
781
782 - `strings` (default: `true`) — compact string concatenations.
783
784 - `switches` (default: `true`) — de-duplicate and remove unreachable `switch` branches
785
786 - `templates` (default: `true`) — compact template literals by embedding expressions
787   and/or converting to string literals, e.g. `` `foo ${42}` → "foo 42"``
788
789 - `top_retain` (default: `null`) — prevent specific toplevel functions and
790   variables from `unused` removal (can be array, comma-separated, RegExp or
791   function. Implies `toplevel`)
792
793 - `toplevel` (default: `false`) — drop unreferenced functions (`"funcs"`) and/or
794   variables (`"vars"`) in the top level scope (`false` by default, `true` to drop
795   both unreferenced functions and variables)
796
797 - `typeofs` (default: `true`) — compress `typeof` expressions, e.g.
798   `typeof foo == "undefined" → void 0 === foo`
799
800 - `unsafe` (default: `false`) — apply "unsafe" transformations (discussion below)
801
802 - `unsafe_comps` (default: `false`) — compress expressions like `a <= b` assuming
803   none of the operands can be (coerced to) `NaN`.
804
805 - `unsafe_Function` (default: `false`) — compress and mangle `Function(args, code)`
806   when both `args` and `code` are string literals.
807
808 - `unsafe_math` (default: `false`) — optimize numerical expressions like
809   `2 * x * 3` into `6 * x`, which may give imprecise floating point results.
810
811 - `unsafe_proto` (default: `false`) — optimize expressions like
812   `Array.prototype.slice.call(a)` into `[].slice.call(a)`
813
814 - `unsafe_regexp` (default: `false`) — enable substitutions of variables with
815   `RegExp` values the same way as if they are constants.
816
817 - `unsafe_undefined` (default: `false`) — substitute `void 0` if there is a
818   variable named `undefined` in scope (variable name will be mangled, typically
819   reduced to a single character)
820
821 - `unused` (default: `true`) — drop unreferenced functions and variables (simple
822   direct variable assignments do not count as references unless set to `"keep_assign"`)
823
824 - `varify` (default: `true`) — convert block-scoped declaractions into `var`
825   whenever safe to do so
826
827 - `yields` (default: `true`) — apply optimizations to `yield` expressions
828
829 ## Mangle options
830
831 - `eval` (default: `false`) — Pass `true` to mangle names visible in scopes
832   where `eval` or `with` are used.
833
834 - `reserved` (default: `[]`) — Pass an array of identifiers that should be
835   excluded from mangling. Example: `["foo", "bar"]`.
836
837 - `toplevel` (default: `false`) — Pass `true` to mangle names declared in the
838   top level scope.
839
840 Examples:
841
842 ```javascript
843 // test.js
844 var globalVar;
845 function funcName(firstLongName, anotherLongName) {
846     var myVariable = firstLongName +  anotherLongName;
847 }
848 ```
849 ```javascript
850 var code = fs.readFileSync("test.js", "utf8");
851
852 UglifyJS.minify(code).code;
853 // 'function funcName(a,n){}var globalVar;'
854
855 UglifyJS.minify(code, { mangle: { reserved: ['firstLongName'] } }).code;
856 // 'function funcName(firstLongName,a){}var globalVar;'
857
858 UglifyJS.minify(code, { mangle: { toplevel: true } }).code;
859 // 'function n(n,a){}var a;'
860 ```
861
862 ### Mangle properties options
863
864 - `builtins` (default: `false`) — Use `true` to allow the mangling of builtin
865   DOM properties. Not recommended to override this setting.
866
867 - `debug` (default: `false`) — Mangle names with the original name still present.
868   Pass an empty string `""` to enable, or a non-empty string to set the debug suffix.
869
870 - `keep_quoted` (default: `false`) — Only mangle unquoted property names.
871
872 - `regex` (default: `null`) — Pass a RegExp literal to only mangle property
873   names matching the regular expression.
874
875 - `reserved` (default: `[]`) — Do not mangle property names listed in the
876   `reserved` array.
877
878 ## Output options
879
880 The code generator tries to output shortest code possible by default.  In
881 case you want beautified output, pass `--beautify` (`-b`).  Optionally you
882 can pass additional arguments that control the code output:
883
884 - `annotations` (default: `false`) — pass `true` to retain comment annotations
885   `/*@__PURE__*/` or `/*#__PURE__*/`, otherwise they will be discarded even if
886   `comments` is set.
887
888 - `ascii_only` (default: `false`) — escape Unicode characters in strings and
889   regexps (affects directives with non-ascii characters becoming invalid)
890
891 - `beautify` (default: `true`) — whether to actually beautify the output.
892   Passing `-b` will set this to true, but you might need to pass `-b` even
893   when you want to generate minified code, in order to specify additional
894   arguments, so you can use `-b beautify=false` to override it.
895
896 - `braces` (default: `false`) — always insert braces in `if`, `for`,
897   `do`, `while` or `with` statements, even if their body is a single
898   statement.
899
900 - `comments` (default: `false`) — pass `true` or `"all"` to preserve all
901   comments, `"some"` to preserve multi-line comments that contain `@cc_on`,
902   `@license`, or `@preserve` (case-insensitive), a regular expression string
903   (e.g. `/^!/`), or a function which returns `boolean`, e.g.
904   ```javascript
905   function(node, comment) {
906       return comment.value.indexOf("@type " + node.TYPE) >= 0;
907   }
908   ```
909
910 - `galio` (default: `false`) — enable workarounds for ANT Galio bugs
911
912 - `indent_level` (default: `4`)
913
914 - `indent_start` (default: `0`) — prefix all lines by that many spaces
915
916 - `inline_script` (default: `true`) — escape HTML comments and the slash in
917   occurrences of `</script>` in strings
918
919 - `keep_quoted_props` (default: `false`) — when turned on, prevents stripping
920   quotes from property names in object literals.
921
922 - `max_line_len` (default: `false`) — maximum line length (for uglified code)
923
924 - `preamble` (default: `null`) — when passed it must be a string and
925   it will be prepended to the output literally.  The source map will
926   adjust for this text.  Can be used to insert a comment containing
927   licensing information, for example.
928
929 - `preserve_line` (default: `false`) — pass `true` to retain line numbering on
930   a best effort basis.
931
932 - `quote_keys` (default: `false`) — pass `true` to quote all keys in literal
933   objects
934
935 - `quote_style` (default: `0`) — preferred quote style for strings (affects
936   quoted property names and directives as well):
937   - `0` — prefers double quotes, switches to single quotes when there are
938     more double quotes in the string itself. `0` is best for gzip size.
939   - `1` — always use single quotes
940   - `2` — always use double quotes
941   - `3` — always use the original quotes
942
943 - `semicolons` (default: `true`) — separate statements with semicolons.  If
944   you pass `false` then whenever possible we will use a newline instead of a
945   semicolon, leading to more readable output of uglified code (size before
946   gzip could be smaller; size after gzip insignificantly larger).
947
948 - `shebang` (default: `true`) — preserve shebang `#!` in preamble (bash scripts)
949
950 - `width` (default: `80`) — only takes effect when beautification is on, this
951   specifies an (orientative) line width that the beautifier will try to
952   obey.  It refers to the width of the line text (excluding indentation).
953   It doesn't work very well currently, but it does make the code generated
954   by UglifyJS more readable.
955
956 - `wrap_iife` (default: `false`) — pass `true` to wrap immediately invoked
957   function expressions. See
958   [#640](https://github.com/mishoo/UglifyJS/issues/640) for more details.
959
960 # Miscellaneous
961
962 ### Keeping copyright notices or other comments
963
964 You can pass `--comments` to retain certain comments in the output.  By
965 default it will keep JSDoc-style comments that contain "@preserve",
966 "@license" or "@cc_on" (conditional compilation for IE).  You can pass
967 `--comments all` to keep all the comments, or a valid JavaScript regexp to
968 keep only comments that match this regexp.  For example `--comments /^!/`
969 will keep comments like `/*! Copyright Notice */`.
970
971 Note, however, that there might be situations where comments are lost.  For
972 example:
973 ```javascript
974 function f() {
975     /** @preserve Foo Bar */
976     function g() {
977         // this function is never called
978     }
979     return something();
980 }
981 ```
982
983 Even though it has "@preserve", the comment will be lost because the inner
984 function `g` (which is the AST node to which the comment is attached to) is
985 discarded by the compressor as not referenced.
986
987 The safest comments where to place copyright information (or other info that
988 needs to be kept in the output) are comments attached to toplevel nodes.
989
990 ### The `unsafe` `compress` option
991
992 It enables some transformations that *might* break code logic in certain
993 contrived cases, but should be fine for most code.  You might want to try it
994 on your own code, it should reduce the minified size.  Here's what happens
995 when this flag is on:
996
997 - `new Array(1, 2, 3)` or `Array(1, 2, 3)` → `[ 1, 2, 3 ]`
998 - `new Object()` → `{}`
999 - `String(exp)` or `exp.toString()` → `"" + exp`
1000 - `new Object/RegExp/Function/Error/Array (...)` → we discard the `new`
1001
1002 ### Conditional compilation
1003
1004 You can use the `--define` (`-d`) switch in order to declare global
1005 variables that UglifyJS will assume to be constants (unless defined in
1006 scope).  For example if you pass `--define DEBUG=false` then, coupled with
1007 dead code removal UglifyJS will discard the following from the output:
1008 ```javascript
1009 if (DEBUG) {
1010     console.log("debug stuff");
1011 }
1012 ```
1013
1014 You can specify nested constants in the form of `--define env.DEBUG=false`.
1015
1016 UglifyJS will warn about the condition being always false and about dropping
1017 unreachable code; for now there is no option to turn off only this specific
1018 warning, you can pass `warnings=false` to turn off *all* warnings.
1019
1020 Another way of doing that is to declare your globals as constants in a
1021 separate file and include it into the build.  For example you can have a
1022 `build/defines.js` file with the following:
1023 ```javascript
1024 var DEBUG = false;
1025 var PRODUCTION = true;
1026 // etc.
1027 ```
1028
1029 and build your code like this:
1030
1031     uglifyjs build/defines.js js/foo.js js/bar.js... -c
1032
1033 UglifyJS will notice the constants and, since they cannot be altered, it
1034 will evaluate references to them to the value itself and drop unreachable
1035 code as usual.  The build will contain the `const` declarations if you use
1036 them. If you are targeting < ES6 environments which does not support `const`,
1037 using `var` with `reduce_vars` (enabled by default) should suffice.
1038
1039 ### Conditional compilation API
1040
1041 You can also use conditional compilation via the programmatic API. With the difference that the
1042 property name is `global_defs` and is a compressor property:
1043
1044 ```javascript
1045 var result = UglifyJS.minify(fs.readFileSync("input.js", "utf8"), {
1046     compress: {
1047         dead_code: true,
1048         global_defs: {
1049             DEBUG: false
1050         }
1051     }
1052 });
1053 ```
1054
1055 To replace an identifier with an arbitrary non-constant expression it is
1056 necessary to prefix the `global_defs` key with `"@"` to instruct UglifyJS
1057 to parse the value as an expression:
1058 ```javascript
1059 UglifyJS.minify("alert('hello');", {
1060     compress: {
1061         global_defs: {
1062             "@alert": "console.log"
1063         }
1064     }
1065 }).code;
1066 // returns: 'console.log("hello");'
1067 ```
1068
1069 Otherwise it would be replaced as string literal:
1070 ```javascript
1071 UglifyJS.minify("alert('hello');", {
1072     compress: {
1073         global_defs: {
1074             "alert": "console.log"
1075         }
1076     }
1077 }).code;
1078 // returns: '"console.log"("hello");'
1079 ```
1080
1081 ### Using native Uglify AST with `minify()`
1082 ```javascript
1083 // example: parse only, produce native Uglify AST
1084
1085 var result = UglifyJS.minify(code, {
1086     parse: {},
1087     compress: false,
1088     mangle: false,
1089     output: {
1090         ast: true,
1091         code: false  // optional - faster if false
1092     }
1093 });
1094
1095 // result.ast contains native Uglify AST
1096 ```
1097 ```javascript
1098 // example: accept native Uglify AST input and then compress and mangle
1099 //          to produce both code and native AST.
1100
1101 var result = UglifyJS.minify(ast, {
1102     compress: {},
1103     mangle: {},
1104     output: {
1105         ast: true,
1106         code: true  // optional - faster if false
1107     }
1108 });
1109
1110 // result.ast contains native Uglify AST
1111 // result.code contains the minified code in string form.
1112 ```
1113
1114 ### Working with Uglify AST
1115
1116 Transversal and transformation of the native AST can be performed through
1117 [`TreeWalker`](https://github.com/mishoo/UglifyJS/blob/master/lib/ast.js) and
1118 [`TreeTransformer`](https://github.com/mishoo/UglifyJS/blob/master/lib/transform.js)
1119 respectively.
1120
1121 ### ESTree / SpiderMonkey AST
1122
1123 UglifyJS has its own abstract syntax tree format; for
1124 [practical reasons](http://lisperator.net/blog/uglifyjs-why-not-switching-to-spidermonkey-ast/)
1125 we can't easily change to using the SpiderMonkey AST internally.  However,
1126 UglifyJS now has a converter which can import a SpiderMonkey AST.
1127
1128 For example [Acorn][acorn] is a super-fast parser that produces a
1129 SpiderMonkey AST.  It has a small CLI utility that parses one file and dumps
1130 the AST in JSON on the standard output.  To use UglifyJS to mangle and
1131 compress that:
1132
1133     acorn file.js | uglifyjs -p spidermonkey -m -c
1134
1135 The `-p spidermonkey` option tells UglifyJS that all input files are not
1136 JavaScript, but JS code described in SpiderMonkey AST in JSON.  Therefore we
1137 don't use our own parser in this case, but just transform that AST into our
1138 internal AST.
1139
1140 ### Use Acorn for parsing
1141
1142 More for fun, I added the `-p acorn` option which will use Acorn to do all
1143 the parsing.  If you pass this option, UglifyJS will `require("acorn")`.
1144
1145 Acorn is really fast (e.g. 250ms instead of 380ms on some 650K code), but
1146 converting the SpiderMonkey tree that Acorn produces takes another 150ms so
1147 in total it's a bit more than just using UglifyJS's own parser.
1148
1149 [acorn]: https://github.com/ternjs/acorn
1150 [sm-spec]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k
1151
1152 ### Uglify Fast Minify Mode
1153
1154 It's not well known, but whitespace removal and symbol mangling accounts
1155 for 95% of the size reduction in minified code for most JavaScript - not
1156 elaborate code transforms. One can simply disable `compress` to speed up
1157 Uglify builds by 3 to 5 times.
1158
1159 | d3.js | minify size | gzip size | minify time (seconds) |
1160 | --- | ---: | ---: | ---: |
1161 | original | 511,371 | 119,932 | - |
1162 | uglify-js@3.13.0 mangle=false, compress=false | 363,988 | 95,695 | 0.56 |
1163 | uglify-js@3.13.0 mangle=true, compress=false | 253,305 | 81,281 | 0.99 |
1164 | uglify-js@3.13.0 mangle=true, compress=true | 244,436 | 79,854 | 5.30 |
1165
1166 To enable fast minify mode from the CLI use:
1167 ```
1168 uglifyjs file.js -m
1169 ```
1170 To enable fast minify mode with the API use:
1171 ```javascript
1172 UglifyJS.minify(code, { compress: false, mangle: true });
1173 ```
1174
1175 ### Source maps and debugging
1176
1177 Various `compress` transforms that simplify, rearrange, inline and remove code
1178 are known to have an adverse effect on debugging with source maps. This is
1179 expected as code is optimized and mappings are often simply not possible as
1180 some code no longer exists. For highest fidelity in source map debugging
1181 disable the Uglify `compress` option and just use `mangle`.
1182
1183 ### Compiler assumptions
1184
1185 To allow for better optimizations, the compiler makes various assumptions:
1186
1187 - The code does not rely on preserving its runtime performance characteristics.
1188   Typically uglified code will run faster due to less instructions and easier
1189   inlining, but may be slower on rare occasions for a specific platform, e.g.
1190   see [`reduce_funcs`](#compress-options).
1191 - `.toString()` and `.valueOf()` don't have side effects, and for built-in
1192   objects they have not been overridden.
1193 - `undefined`, `NaN` and `Infinity` have not been externally redefined.
1194 - `arguments.callee`, `arguments.caller` and `Function.prototype.caller` are not used.
1195 - The code doesn't expect the contents of `Function.prototype.toString()` or
1196   `Error.prototype.stack` to be anything in particular.
1197 - Getting and setting properties on a plain object does not cause other side effects
1198   (using `.watch()` or `Proxy`).
1199 - Object properties can be added, removed and modified (not prevented with
1200   `Object.defineProperty()`, `Object.defineProperties()`, `Object.freeze()`,
1201   `Object.preventExtensions()` or `Object.seal()`).
1202 - If array destructuring is present, index-like properties in `Array.prototype`
1203   have not been overridden:
1204   ```javascript
1205   Object.prototype[0] = 42;
1206   var [ a ] = [];
1207   var { 0: b } = {};
1208   // 42 undefined
1209   console.log([][0], a);
1210   // 42 42
1211   console.log({}[0], b);
1212   ```
1213 - Earlier versions of JavaScript will throw `SyntaxError` with the following:
1214   ```javascript
1215   ({
1216       p: 42,
1217       get p() {},
1218   });
1219   // SyntaxError: Object literal may not have data and accessor property with
1220   //              the same name
1221   ```
1222   UglifyJS may modify the input which in turn may suppress those errors.
1223 - Iteration order of keys over an object which contains spread syntax in later
1224   versions of Chrome and Node.js may be altered.
1225 - When `toplevel` is enabled, UglifyJS effectively assumes input code is wrapped
1226   within `function(){ ... }`, thus forbids aliasing of declared global variables:
1227   ```javascript
1228   A = "FAIL";
1229   var B = "FAIL";
1230   // can be `global`, `self`, `window` etc.
1231   var top = function() {
1232       return this;
1233   }();
1234   // "PASS"
1235   top.A = "PASS";
1236   console.log(A);
1237   // "FAIL" after compress and/or mangle
1238   top.B = "PASS";
1239   console.log(B);
1240   ```
1241 - Use of `arguments` alongside destructuring as function parameters, e.g.
1242   `function({}, arguments) {}` will result in `SyntaxError` in earlier versions
1243   of Chrome and Node.js - UglifyJS may modify the input which in turn may
1244   suppress those errors.
1245 - Earlier versions of Chrome and Node.js will throw `ReferenceError` with the
1246   following:
1247   ```javascript
1248   var a;
1249   try {
1250       throw 42;
1251   } catch ({
1252       [a]: b,
1253       // ReferenceError: a is not defined
1254   }) {
1255       let a;
1256   }
1257   ```
1258   UglifyJS may modify the input which in turn may suppress those errors.
1259 - Later versions of JavaScript will throw `SyntaxError` with the following:
1260   ```javascript
1261   a => {
1262       let a;
1263   };
1264   // SyntaxError: Identifier 'a' has already been declared
1265   ```
1266   UglifyJS may modify the input which in turn may suppress those errors.
1267 - Later versions of JavaScript will throw `SyntaxError` with the following:
1268   ```javascript
1269   try {
1270       // ...
1271   } catch ({ message: a }) {
1272       var a;
1273   }
1274   // SyntaxError: Identifier 'a' has already been declared
1275   ```
1276   UglifyJS may modify the input which in turn may suppress those errors.
1277 - Some versions of Chrome and Node.js will throw `ReferenceError` with the
1278   following:
1279   ```javascript
1280   console.log(((a, b = function() {
1281       return a;
1282       // ReferenceError: a is not defined
1283   }()) => b)());
1284   ```
1285   UglifyJS may modify the input which in turn may suppress those errors.
1286 - Some arithmetic operations with `BigInt` may throw `TypeError`:
1287   ```javascript
1288   1n + 1;
1289   // TypeError: can't convert BigInt to number
1290   ```
1291   UglifyJS may modify the input which in turn may suppress those errors.
1292 - Some versions of JavaScript will throw `SyntaxError` with the
1293   following:
1294   ```javascript
1295   console.log(String.raw`\uFo`);
1296   // SyntaxError: Invalid Unicode escape sequence
1297   ```
1298   UglifyJS may modify the input which in turn may suppress those errors.
1299 - Some versions of JavaScript will throw `SyntaxError` with the
1300   following:
1301   ```javascript
1302   try {} catch (e) {
1303       for (var e of []);
1304   }
1305   // SyntaxError: Identifier 'e' has already been declared
1306   ```
1307   UglifyJS may modify the input which in turn may suppress those errors.
1308 - Some versions of Chrome and Node.js will give incorrect results with the
1309   following:
1310   ```javascript
1311   console.log({
1312       ...{
1313           set 42(v) {},
1314           42: "PASS",
1315       },
1316   });
1317   // Expected: { '42': 'PASS' }
1318   // Actual:   { '42': undefined }
1319   ```
1320   UglifyJS may modify the input which in turn may suppress those errors.
1321 - Later versions of JavaScript will throw `SyntaxError` with the following:
1322   ```javascript
1323   var await;
1324   async function f() {
1325       class A {
1326           static p = await;
1327       }
1328   }
1329   // SyntaxError: Unexpected reserved word
1330   ```
1331   UglifyJS may modify the input which in turn may suppress those errors.
1332 - Later versions of JavaScript will throw `SyntaxError` with the following:
1333   ```javascript
1334   var async;
1335   for (async of []);
1336   // SyntaxError: The left-hand side of a for-of loop may not be 'async'.
1337   ```
1338   UglifyJS may modify the input which in turn may suppress those errors.
1339 - Later versions of Chrome and Node.js will give incorrect results with the
1340   following:
1341   ```javascript
1342   console.log({
1343       ...console,
1344       get 42() {
1345           return "FAIL";
1346       },
1347       [42]: "PASS",
1348   }[42]);
1349   // Expected: "PASS"
1350   // Actual:   "FAIL"
1351   ```
1352   UglifyJS may modify the input which in turn may suppress those errors.
1353 - Earlier versions of JavaScript will throw `TypeError` with the following:
1354   ```javascript
1355   (function() {
1356       {
1357           const a = "foo";
1358       }
1359       {
1360           const a = "bar";
1361       }
1362   })();
1363   // TypeError: const 'a' has already been declared
1364   ```
1365   UglifyJS may modify the input which in turn may suppress those errors.