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