4 UglifyJS is a JavaScript parser, minifier, compressor and beautifier toolkit.
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).
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).
19 From NPM for use as a command line app:
21 npm install uglify-js -g
23 From NPM for programmatic use:
29 uglifyjs [input files] [options]
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.
37 If no input file is specified, UglifyJS will read from STDIN.
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:
42 uglifyjs --compress --mangle -- input.js
44 ### Command line options
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
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
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
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:
88 `wrap_iife` Wrap IIFEs in parentheses. Note: you may
89 want to disable `negate_iife` under
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
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
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.
157 Specify `--output` (`-o`) to declare the output file. Otherwise the output
160 ## CLI source map options
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
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])
173 - `--source-map "root='<URL>'"` to pass the URL where the original files can be found.
175 - `--source-map "names=false"` to omit symbol names if you want to reduce size
176 of the source map file.
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.
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'"
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
195 ### Composed source map
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
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
209 ## CLI compress options
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).
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`).
220 uglifyjs file.js -c toplevel,sequences=false
222 ## CLI mangle options
224 To enable the mangler you need to pass `--mangle` (`-m`). The following
225 (comma-separated) options are supported:
227 - `eval` (default: `false`) — mangle names visible in scopes where `eval` or
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:
234 uglifyjs ... -m reserved=['$','require','exports']
236 to prevent the `require`, `exports` and `$` names from being changed.
238 ### CLI mangling property names (`--mangle-props`)
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:
252 return this.foo_ + this.baz_;
257 console.log(x.calc());
259 Mangle all properties (except for JavaScript `builtins`):
261 $ uglifyjs example.js -c -m --mangle-props
264 var x={o:0,_:1,l:function(){return this._+this.o}};x.t=2,x.o=3,console.log(x.l());
266 Mangle all properties except for `reserved` properties:
268 $ uglifyjs example.js -c -m --mangle-props reserved=[foo_,bar_]
271 var x={o:0,foo_:1,_:function(){return this.foo_+this.o}};x.bar_=2,x.o=3,console.log(x._());
273 Mangle all properties matching a `regex`:
275 $ uglifyjs example.js -c -m --mangle-props regex=/_$/
278 var x={o:0,_:1,calc:function(){return this._+this.o}};x.l=2,x.o=3,console.log(x.calc());
281 Combining mangle properties options:
283 $ uglifyjs example.js -c -m --mangle-props regex=/_$/,reserved=[bar_]
286 var x={o:0,_:1,calc:function(){return this._+this.o}};x.bar_=2,x.o=3,console.log(x.calc());
289 In order for this to be of any use, we avoid mangling standard JS names by
290 default (`--mangle-props builtins` to override).
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.
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.
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:
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
312 Now, `part1.js` and `part2.js` will be consistent with each other in terms
313 of mangled property names.
315 Using the name cache is not necessary if you compress all your files in a
316 single call to UglifyJS.
318 ### Mangling unquoted names (`--mangle-props keep_quoted`)
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:
334 $ uglifyjs stuff.js --mangle-props keep_quoted -c -m
337 var o={foo:1,o:3};o.foo+=o.o,console.log(o.foo);
340 ### Debugging property name mangling
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.
349 $ uglifyjs stuff.js --mangle-props debug -c -m
352 var o={_$foo$_:1,_$bar$_:3};o._$foo$_+=o._$bar$_,console.log(o._$foo$_);
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.
365 Assuming installation via NPM, you can load UglifyJS in your application
368 var UglifyJS = require("uglify-js");
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:
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}
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
387 "file1.js": "function add(first, second) { return first + second; }",
388 "file2.js": "console.log(add(1 + 2, 3 + 4));"
390 var result = UglifyJS.minify(code);
391 console.log(result.code);
392 // function add(d,n){return d+n}console.log(add(3,7));
395 The `toplevel` option:
398 "file1.js": "function add(first, second) { return first + second; }",
399 "file2.js": "console.log(add(1 + 2, 3 + 4));"
401 var options = { toplevel: true };
402 var result = UglifyJS.minify(code, options);
403 console.log(result.code);
407 The `nameCache` option:
415 var result1 = UglifyJS.minify({
416 "file1.js": "function add(first, second) { return first + second; }"
418 var result2 = UglifyJS.minify({
419 "file2.js": "console.log(add(1 + 2, 3 + 4));"
421 console.log(result1.code);
422 // function n(n,r){return n+r}
423 console.log(result2.code);
424 // console.log(n(3,7));
427 You may persist the name cache to the file system in the following way:
429 var cacheFileName = "/tmp/cache.json";
434 nameCache: JSON.parse(fs.readFileSync(cacheFileName, "utf8"))
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");
447 An example of a combination of `minify()` options:
450 "file1.js": "function add(first, second) { return first + second; }",
451 "file2.js": "console.log(add(1 + 2, 3 + 4));"
457 "@console.log": "alert"
463 preamble: "/* uglified */"
466 var result = UglifyJS.minify(code, options);
467 console.log(result.code);
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}
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}
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:
491 var result = UglifyJS.minify(code, options);
492 if (result.error) throw result.error;
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.
502 - `compress` (default: `{}`) — pass `false` to skip compressing entirely.
503 Pass an object to specify custom [compress options](#compress-options).
505 - `ie` (default: `false`) — enable workarounds for Internet Explorer bugs.
507 - `keep_fnames` (default: `false`) — pass `true` to prevent discarding or mangling
508 of function names. Useful for code relying on `Function.prototype.name`.
510 - `mangle` (default: `true`) — pass `false` to skip mangling names, or pass
511 an object to specify [mangle options](#mangle-options) (see below).
513 - `mangle.properties` (default: `false`) — a subcategory of the mangle option.
514 Pass an object to specify custom [mangle property options](#mangle-properties-options).
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.
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.
527 - `parse` (default: `{}`) — pass an object if you wish to specify some
528 additional [parse options](#parse-options).
530 - `sourceMap` (default: `false`) — pass an object if you wish to specify
531 [source map options](#source-map-options).
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.
536 - `v8` (default: `false`) — enable workarounds for Chrome & Node.js bugs.
538 - `warnings` (default: `false`) — pass `true` to return compressor warnings
539 in `result.warnings`. Use the value `"verbose"` for more detailed warnings.
541 - `webkit` (default: `false`) — enable workarounds for Safari/WebKit bugs.
542 PhantomJS users should set this option to `true`.
544 ## Minify options structure
558 // mangle property options
565 // source map options
567 nameCache: null, // or specify a name cache object
573 ### Source map options
575 To generate a source map:
577 var result = UglifyJS.minify({"file1.js": "var a = function() {};"}, {
583 console.log(result.code); // minified output
584 console.log(result.map); // source map
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])
593 You can set option `sourceMap.url` to be `"inline"` and source map will
596 You can also specify sourceRoot property to be included in source map:
598 var result = UglifyJS.minify({"file1.js": "var a = function() {};"}, {
600 root: "http://example.com/src",
606 If you're compressing compiled JavaScript and have a source map for it, you
607 can use `sourceMap.content`:
609 var result = UglifyJS.minify({"compiled.js": "compiled code"}, {
611 content: "content from compiled.js.map",
612 url: "minified.js.map"
615 // same as before, it returns `code` and `map`
618 If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.url`.
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.
625 - `bare_returns` (default: `false`) — support top level `return` statements
627 - `html5_comments` (default: `true`)
629 - `shebang` (default: `true`) — support `#!command` as the first line
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();`
638 - `arguments` (default: `true`) — replace `arguments[index]` with function
639 parameter name whenever possible.
641 - `arrows` (default: `true`) — apply optimizations to arrow functions
643 - `assignments` (default: `true`) — apply optimizations to assignment expressions
645 - `awaits` (default: `true`) — apply optimizations to `await` expressions
647 - `booleans` (default: `true`) — various optimizations for boolean context,
648 for example `!!a ? b : c → a ? b : c`
650 - `collapse_vars` (default: `true`) — Collapse single-use non-constant variables,
651 side effects permitting.
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.
657 - `conditionals` (default: `true`) — apply optimizations for `if`-s and conditional
660 - `dead_code` (default: `true`) — remove unreachable code
662 - `default_values` (default: `true`) — drop overshadowed default values
664 - `directives` (default: `true`) — remove redundant or non-standard directives
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.
671 - `drop_debugger` (default: `true`) — remove `debugger;` statements
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.
678 - `expression` (default: `false`) — Pass `true` to preserve completion values
679 from terminal statements without `return`, e.g. in bookmarklets.
681 - `functions` (default: `true`) — convert declarations from `var` to `function`
684 - `global_defs` (default: `{}`) — see [conditional compilation](#conditional-compilation)
686 - `hoist_exports` (default: `true`) — hoist `export` statements to facilitate
687 various `compress` and `mangle` optimizations.
689 - `hoist_funs` (default: `false`) — hoist function declarations
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.
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)
700 - `if_return` (default: `true`) — optimizations for if/return and if/continue
702 - `imports` (default: `true`) — drop unreferenced import symbols when used with `unused`
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`
712 - `join_vars` (default: `true`) — join consecutive `var` statements
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.
718 - `keep_infinity` (default: `false`) — Pass `true` to prevent `Infinity` from
719 being compressed into `1/0`, which may cause performance issues on Chrome.
721 - `loops` (default: `true`) — optimizations for `do`, `while` and `for` loops
722 when we can statically determine the condition.
724 - `merge_vars` (default: `true`) — combine and reuse variables.
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.
730 - `objects` (default: `true`) — compact duplicate keys in object literals.
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.
736 - `properties` (default: `true`) — rewrite property access using the dot notation, for
737 example `foo["bar"] → foo.bar`
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.
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`.
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.
763 - `reduce_vars` (default: `true`) — Improve optimization on variables assigned with and
764 used as constant values.
766 - `rests` (default: `true`) — apply optimizations to rest parameters
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.
777 - `side_effects` (default: `true`) — drop extraneous code which does not affect
778 outcome of runtime execution.
780 - `spreads` (default: `true`) — flatten spread expressions.
782 - `strings` (default: `true`) — compact string concatenations.
784 - `switches` (default: `true`) — de-duplicate and remove unreachable `switch` branches
786 - `templates` (default: `true`) — compact template literals by embedding expressions
787 and/or converting to string literals, e.g. `` `foo ${42}` → "foo 42"``
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`)
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)
797 - `typeofs` (default: `true`) — compress `typeof` expressions, e.g.
798 `typeof foo == "undefined" → void 0 === foo`
800 - `unsafe` (default: `false`) — apply "unsafe" transformations (discussion below)
802 - `unsafe_comps` (default: `false`) — compress expressions like `a <= b` assuming
803 none of the operands can be (coerced to) `NaN`.
805 - `unsafe_Function` (default: `false`) — compress and mangle `Function(args, code)`
806 when both `args` and `code` are string literals.
808 - `unsafe_math` (default: `false`) — optimize numerical expressions like
809 `2 * x * 3` into `6 * x`, which may give imprecise floating point results.
811 - `unsafe_proto` (default: `false`) — optimize expressions like
812 `Array.prototype.slice.call(a)` into `[].slice.call(a)`
814 - `unsafe_regexp` (default: `false`) — enable substitutions of variables with
815 `RegExp` values the same way as if they are constants.
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)
821 - `unused` (default: `true`) — drop unreferenced functions and variables (simple
822 direct variable assignments do not count as references unless set to `"keep_assign"`)
824 - `varify` (default: `true`) — convert block-scoped declaractions into `var`
825 whenever safe to do so
827 - `yields` (default: `true`) — apply optimizations to `yield` expressions
831 - `eval` (default: `false`) — Pass `true` to mangle names visible in scopes
832 where `eval` or `with` are used.
834 - `reserved` (default: `[]`) — Pass an array of identifiers that should be
835 excluded from mangling. Example: `["foo", "bar"]`.
837 - `toplevel` (default: `false`) — Pass `true` to mangle names declared in the
845 function funcName(firstLongName, anotherLongName) {
846 var myVariable = firstLongName + anotherLongName;
850 var code = fs.readFileSync("test.js", "utf8");
852 UglifyJS.minify(code).code;
853 // 'function funcName(a,n){}var globalVar;'
855 UglifyJS.minify(code, { mangle: { reserved: ['firstLongName'] } }).code;
856 // 'function funcName(firstLongName,a){}var globalVar;'
858 UglifyJS.minify(code, { mangle: { toplevel: true } }).code;
859 // 'function n(n,a){}var a;'
862 ### Mangle properties options
864 - `builtins` (default: `false`) — Use `true` to allow the mangling of builtin
865 DOM properties. Not recommended to override this setting.
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.
870 - `keep_quoted` (default: `false`) — Only mangle unquoted property names.
872 - `regex` (default: `null`) — Pass a RegExp literal to only mangle property
873 names matching the regular expression.
875 - `reserved` (default: `[]`) — Do not mangle property names listed in the
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:
884 - `annotations` (default: `false`) — pass `true` to retain comment annotations
885 `/*@__PURE__*/` or `/*#__PURE__*/`, otherwise they will be discarded even if
888 - `ascii_only` (default: `false`) — escape Unicode characters in strings and
889 regexps (affects directives with non-ascii characters becoming invalid)
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.
896 - `braces` (default: `false`) — always insert braces in `if`, `for`,
897 `do`, `while` or `with` statements, even if their body is a single
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.
905 function(node, comment) {
906 return comment.value.indexOf("@type " + node.TYPE) >= 0;
910 - `galio` (default: `false`) — enable workarounds for ANT Galio bugs
912 - `indent_level` (default: `4`)
914 - `indent_start` (default: `0`) — prefix all lines by that many spaces
916 - `inline_script` (default: `true`) — escape HTML comments and the slash in
917 occurrences of `</script>` in strings
919 - `keep_quoted_props` (default: `false`) — when turned on, prevents stripping
920 quotes from property names in object literals.
922 - `max_line_len` (default: `false`) — maximum line length (for uglified code)
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.
929 - `preserve_line` (default: `false`) — pass `true` to retain line numbering on
932 - `quote_keys` (default: `false`) — pass `true` to quote all keys in literal
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
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).
948 - `shebang` (default: `true`) — preserve shebang `#!` in preamble (bash scripts)
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.
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.
962 ### Keeping copyright notices or other comments
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 */`.
971 Note, however, that there might be situations where comments are lost. For
975 /** @preserve Foo Bar */
977 // this function is never called
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.
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.
990 ### The `unsafe` `compress` option
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:
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`
1002 ### Conditional compilation
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:
1010 console.log("debug stuff");
1014 You can specify nested constants in the form of `--define env.DEBUG=false`.
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.
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:
1025 var PRODUCTION = true;
1029 and build your code like this:
1031 uglifyjs build/defines.js js/foo.js js/bar.js... -c
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.
1039 ### Conditional compilation API
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:
1045 var result = UglifyJS.minify(fs.readFileSync("input.js", "utf8"), {
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:
1059 UglifyJS.minify("alert('hello');", {
1062 "@alert": "console.log"
1066 // returns: 'console.log("hello");'
1069 Otherwise it would be replaced as string literal:
1071 UglifyJS.minify("alert('hello');", {
1074 "alert": "console.log"
1078 // returns: '"console.log"("hello");'
1081 ### Using native Uglify AST with `minify()`
1083 // example: parse only, produce native Uglify AST
1085 var result = UglifyJS.minify(code, {
1091 code: false // optional - faster if false
1095 // result.ast contains native Uglify AST
1098 // example: accept native Uglify AST input and then compress and mangle
1099 // to produce both code and native AST.
1101 var result = UglifyJS.minify(ast, {
1106 code: true // optional - faster if false
1110 // result.ast contains native Uglify AST
1111 // result.code contains the minified code in string form.
1114 ### Working with Uglify AST
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)
1121 ### ESTree / SpiderMonkey AST
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.
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
1133 acorn file.js | uglifyjs -p spidermonkey -m -c
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
1140 ### Use Acorn for parsing
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")`.
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.
1149 [acorn]: https://github.com/ternjs/acorn
1150 [sm-spec]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k
1152 ### Uglify Fast Minify Mode
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.
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 |
1166 To enable fast minify mode from the CLI use:
1170 To enable fast minify mode with the API use:
1172 UglifyJS.minify(code, { compress: false, mangle: true });
1175 ### Source maps and debugging
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`.
1183 ### Compiler assumptions
1185 To allow for better optimizations, the compiler makes various assumptions:
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:
1205 Object.prototype[0] = 42;
1209 console.log([][0], a);
1211 console.log({}[0], b);
1213 - Earlier versions of JavaScript will throw `SyntaxError` with the following:
1219 // SyntaxError: Object literal may not have data and accessor property with
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:
1230 // can be `global`, `self`, `window` etc.
1231 var top = function() {
1237 // "FAIL" after compress and/or mangle
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
1253 // ReferenceError: a is not defined
1258 UglifyJS may modify the input which in turn may suppress those errors.
1259 - Later versions of JavaScript will throw `SyntaxError` with the following:
1264 // SyntaxError: Identifier 'a' has already been declared
1266 UglifyJS may modify the input which in turn may suppress those errors.
1267 - Later versions of JavaScript will throw `SyntaxError` with the following:
1271 } catch ({ message: a }) {
1274 // SyntaxError: Identifier 'a' has already been declared
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
1280 console.log(((a, b = function() {
1282 // ReferenceError: a is not defined
1285 UglifyJS may modify the input which in turn may suppress those errors.
1286 - Some arithmetic operations with `BigInt` may throw `TypeError`:
1289 // TypeError: can't convert BigInt to number
1291 UglifyJS may modify the input which in turn may suppress those errors.
1292 - Some versions of JavaScript will throw `SyntaxError` with the
1295 console.log(String.raw`\uFo`);
1296 // SyntaxError: Invalid Unicode escape sequence
1298 UglifyJS may modify the input which in turn may suppress those errors.
1299 - Some versions of JavaScript will throw `SyntaxError` with the
1305 // SyntaxError: Identifier 'e' has already been declared
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
1317 // Expected: { '42': 'PASS' }
1318 // Actual: { '42': undefined }
1320 UglifyJS may modify the input which in turn may suppress those errors.
1321 - Later versions of JavaScript will throw `SyntaxError` with the following:
1324 async function f() {
1329 // SyntaxError: Unexpected reserved word
1331 UglifyJS may modify the input which in turn may suppress those errors.
1332 - Later versions of JavaScript will throw `SyntaxError` with the following:
1336 // SyntaxError: The left-hand side of a for-of loop may not be 'async'.
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
1352 UglifyJS may modify the input which in turn may suppress those errors.
1353 - Earlier versions of JavaScript will throw `TypeError` with the following:
1363 // TypeError: const 'a' has already been declared
1365 UglifyJS may modify the input which in turn may suppress those errors.