UNPKG

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