1UglifyJS 2 2========== 3[](https://travis-ci.org/mishoo/UglifyJS2) 4 5UglifyJS is a JavaScript parser, minifier, compressor or beautifier toolkit. 6 7This page documents the command line utility. For 8[API and internals documentation see my website](http://lisperator.net/uglifyjs/). 9There's also an 10[in-browser online demo](http://lisperator.net/uglifyjs/#demo) (for Firefox, 11Chrome and probably Safari). 12 13#### Note: 14- `uglify-js` only supports ECMAScript 5 (ES5). 15- Support for `const` is [present but incomplete](#support-for-const), and may not be 16 transformed properly. 17- Those wishing to minify ES2015+ (ES6+) should use the `npm` package [**uglify-es**](https://github.com/mishoo/UglifyJS2/tree/harmony). 18 19Install 20------- 21 22First make sure you have installed the latest version of [node.js](http://nodejs.org/) 23(You may need to restart your computer after this step). 24 25From NPM for use as a command line app: 26 27 npm install uglify-js -g 28 29From NPM for programmatic use: 30 31 npm install uglify-js 32 33Usage 34----- 35 36 uglifyjs [input files] [options] 37 38UglifyJS2 can take multiple input files. It's recommended that you pass the 39input files first, then pass the options. UglifyJS will parse input files 40in sequence and apply any compression options. The files are parsed in the 41same global scope, that is, a reference from a file to some 42variable/function declared in another file will be matched properly. 43 44If you want to read from STDIN instead, pass a single dash instead of input 45files. 46 47If you wish to pass your options before the input files, separate the two with 48a double dash to prevent input files being used as option arguments: 49 50 uglifyjs --compress --mangle -- input.js 51 52The available options are: 53 54``` 55 --source-map Specify an output file where to generate source 56 map. 57 --source-map-root The path to the original source to be included 58 in the source map. 59 --source-map-url The path to the source map to be added in //# 60 sourceMappingURL. Defaults to the value passed 61 with --source-map. 62 --source-map-include-sources Pass this flag if you want to include the 63 content of source files in the source map as 64 sourcesContent property. 65 --source-map-inline Write base64-encoded source map to the end of js output. 66 --in-source-map Input source map, useful if you're compressing 67 JS that was generated from some other original 68 code. Specify "inline" if the source map is included 69 inline with the sources. 70 --screw-ie8 Use this flag if you don't wish to support 71 Internet Explorer 6/7/8. 72 By default UglifyJS will not try to be IE-proof. 73 --support-ie8 Use this flag to support Internet Explorer 6/7/8. 74 Equivalent to setting `screw_ie8: false` in `minify()` 75 for `compress`, `mangle` and `output` options. 76 --expr Parse a single expression, rather than a 77 program (for parsing JSON) 78 -p, --prefix Skip prefix for original filenames that appear 79 in source maps. For example -p 3 will drop 3 80 directories from file names and ensure they are 81 relative paths. You can also specify -p 82 relative, which will make UglifyJS figure out 83 itself the relative paths between original 84 sources, the source map and the output file. 85 -o, --output Output file (default STDOUT). 86 -b, --beautify Beautify output/specify output options. 87 -m, --mangle Mangle names/pass mangler options. 88 -r, --reserved Reserved names to exclude from mangling. 89 -c, --compress Enable compressor/pass compressor options, e.g. 90 `-c 'if_return=false,pure_funcs=["Math.pow","console.log"]'` 91 Use `-c` with no argument to enable default compression 92 options. 93 -d, --define Global definitions 94 -e, --enclose Embed everything in a big function, with a 95 configurable parameter/argument list. 96 --comments Preserve copyright comments in the output. By 97 default this works like Google Closure, keeping 98 JSDoc-style comments that contain "@license" or 99 "@preserve". You can optionally pass one of the 100 following arguments to this flag: 101 - "all" to keep all comments 102 - a valid JS RegExp like `/foo/` or `/^!/` to 103 keep only matching comments. 104 Note that currently not *all* comments can be 105 kept when compression is on, because of dead 106 code removal or cascading statements into 107 sequences. 108 --preamble Preamble to prepend to the output. You can use 109 this to insert a comment, for example for 110 licensing information. This will not be 111 parsed, but the source map will adjust for its 112 presence. 113 --stats Display operations run time on STDERR. 114 --acorn Use Acorn for parsing. 115 --spidermonkey Assume input files are SpiderMonkey AST format 116 (as JSON). 117 --self Build itself (UglifyJS2) as a library (implies 118 --wrap=UglifyJS --export-all) 119 --wrap Embed everything in a big function, making the 120 “exports” and “global” variables available. You 121 need to pass an argument to this option to 122 specify the name that your module will take 123 when included in, say, a browser. 124 --export-all Only used when --wrap, this tells UglifyJS to 125 add code to automatically export all globals. 126 --lint Display some scope warnings 127 -v, --verbose Verbose 128 -V, --version Print version number and exit. 129 --noerr Don't throw an error for unknown options in -c, 130 -b or -m. 131 --bare-returns Allow return outside of functions. Useful when 132 minifying CommonJS modules and Userscripts that 133 may be anonymous function wrapped (IIFE) by the 134 .user.js engine `caller`. 135 --keep-fnames Do not mangle/drop function names. Useful for 136 code relying on Function.prototype.name. 137 --reserved-file File containing reserved names 138 --reserve-domprops Make (most?) DOM properties reserved for 139 --mangle-props 140 --mangle-props Mangle property names (default `0`). Set to 141 `true` or `1` to mangle all property names. Set 142 to `unquoted` or `2` to only mangle unquoted 143 property names. Mode `2` also enables the 144 `keep_quoted_props` beautifier option to 145 preserve the quotes around property names and 146 disables the `properties` compressor option to 147 prevent rewriting quoted properties with dot 148 notation. You can override these by setting 149 them explicitly on the command line. 150 --mangle-regex Only mangle property names matching the regex 151 --name-cache File to hold mangled names mappings 152 --pure-funcs Functions that can be safely removed if their 153 return value is not used, e.g. 154 `--pure-funcs Math.floor console.info` 155 (requires `--compress`) 156``` 157 158Specify `--output` (`-o`) to declare the output file. Otherwise the output 159goes to STDOUT. 160 161## Source map options 162 163UglifyJS2 can generate a source map file, which is highly useful for 164debugging your compressed JavaScript. To get a source map, pass 165`--source-map output.js.map` (full path to the file where you want the 166source map dumped). 167 168Additionally you might need `--source-map-root` to pass the URL where the 169original files can be found. In case you are passing full paths to input 170files to UglifyJS, you can use `--prefix` (`-p`) to specify the number of 171directories to drop from the path prefix when declaring files in the source 172map. 173 174For example: 175 176 uglifyjs /home/doe/work/foo/src/js/file1.js \ 177 /home/doe/work/foo/src/js/file2.js \ 178 -o foo.min.js \ 179 --source-map foo.min.js.map \ 180 --source-map-root http://foo.com/src \ 181 -p 5 -c -m 182 183The above will compress and mangle `file1.js` and `file2.js`, will drop the 184output in `foo.min.js` and the source map in `foo.min.js.map`. The source 185mapping will refer to `http://foo.com/src/js/file1.js` and 186`http://foo.com/src/js/file2.js` (in fact it will list `http://foo.com/src` 187as the source map root, and the original files as `js/file1.js` and 188`js/file2.js`). 189 190### Composed source map 191 192When you're compressing JS code that was output by a compiler such as 193CoffeeScript, mapping to the JS code won't be too helpful. Instead, you'd 194like to map back to the original code (i.e. CoffeeScript). UglifyJS has an 195option to take an input source map. Assuming you have a mapping from 196CoffeeScript → compiled JS, UglifyJS can generate a map from CoffeeScript → 197compressed JS by mapping every token in the compiled JS to its original 198location. 199 200To use this feature you need to pass `--in-source-map 201/path/to/input/source.map` or `--in-source-map inline` if the source map is 202included inline with the sources. Normally the input source map should also 203point to the file containing the generated JS, so if that's correct you can 204omit input files from the command line. 205 206## Mangler options 207 208To enable the mangler you need to pass `--mangle` (`-m`). The following 209(comma-separated) options are supported: 210 211- `toplevel` — mangle names declared in the toplevel scope (disabled by 212 default). 213 214- `eval` — mangle names visible in scopes where `eval` or `with` are used 215 (disabled by default). 216 217When mangling is enabled but you want to prevent certain names from being 218mangled, you can declare those names with `--reserved` (`-r`) — pass a 219comma-separated list of names. For example: 220 221 uglifyjs ... -m -r '$,require,exports' 222 223to prevent the `require`, `exports` and `$` names from being changed. 224 225### Mangling property names (`--mangle-props`) 226 227**Note:** this will probably break your code. Mangling property names is a 228separate step, different from variable name mangling. Pass 229`--mangle-props`. It will mangle all properties that are seen in some 230object literal, or that are assigned to. For example: 231 232```js 233var x = { 234 foo: 1 235}; 236 237x.bar = 2; 238x["baz"] = 3; 239x[condition ? "moo" : "boo"] = 4; 240console.log(x.something()); 241``` 242 243In the above code, `foo`, `bar`, `baz`, `moo` and `boo` will be replaced 244with single characters, while `something()` will be left as is. 245 246In order for this to be of any use, we should avoid mangling standard JS 247names. For instance, if your code would contain `x.length = 10`, then 248`length` becomes a candidate for mangling and it will be mangled throughout 249the code, regardless if it's being used as part of your own objects or 250accessing an array's length. To avoid that, you can use `--reserved-file` 251to pass a filename that should contain the names to be excluded from 252mangling. This file can be used both for excluding variable names and 253property names. It could look like this, for example: 254 255```js 256{ 257 "vars": [ "define", "require", ... ], 258 "props": [ "length", "prototype", ... ] 259} 260``` 261 262`--reserved-file` can be an array of file names (either a single 263comma-separated argument, or you can pass multiple `--reserved-file` 264arguments) — in this case it will exclude names from all those files. 265 266A default exclusion file is provided in `tools/domprops.json` which should 267cover most standard JS and DOM properties defined in various browsers. Pass 268`--reserve-domprops` to read that in. 269 270You can also use a regular expression to define which property names should be 271mangled. For example, `--mangle-regex="/^_/"` will only mangle property names 272that start with an underscore. 273 274When you compress multiple files using this option, in order for them to 275work together in the end we need to ensure somehow that one property gets 276mangled to the same name in all of them. For this, pass `--name-cache 277filename.json` and UglifyJS will maintain these mappings in a file which can 278then be reused. It should be initially empty. Example: 279 280``` 281rm -f /tmp/cache.json # start fresh 282uglifyjs file1.js file2.js --mangle-props --name-cache /tmp/cache.json -o part1.js 283uglifyjs file3.js file4.js --mangle-props --name-cache /tmp/cache.json -o part2.js 284``` 285 286Now, `part1.js` and `part2.js` will be consistent with each other in terms 287of mangled property names. 288 289Using the name cache is not necessary if you compress all your files in a 290single call to UglifyJS. 291 292#### Mangling unquoted names (`--mangle-props=unquoted` or `--mangle-props=2`) 293 294Using quoted property name (`o["foo"]`) reserves the property name (`foo`) 295so that it is not mangled throughout the entire script even when used in an 296unquoted style (`o.foo`). Example: 297 298``` 299$ echo 'var o={"foo":1, bar:3}; o.foo += o.bar; console.log(o.foo);' | uglifyjs --mangle-props=2 -mc 300var o={"foo":1,a:3};o.foo+=o.a,console.log(o.foo); 301``` 302 303#### Debugging property name mangling 304 305You can also pass `--mangle-props-debug` in order to mangle property names 306without completely obscuring them. For example the property `o.foo` 307would mangle to `o._$foo$_` with this option. This allows property mangling 308of a large codebase while still being able to debug the code and identify 309where mangling is breaking things. 310 311You can also pass a custom suffix using `--mangle-props-debug=XYZ`. This would then 312mangle `o.foo` to `o._$foo$XYZ_`. You can change this each time you compile a 313script to identify how a property got mangled. One technique is to pass a 314random number on every compile to simulate mangling changing with different 315inputs (e.g. as you update the input script with new properties), and to help 316identify mistakes like writing mangled keys to storage. 317 318## Compressor options 319 320You need to pass `--compress` (`-c`) to enable the compressor. Optionally 321you can pass a comma-separated list of options. Options are in the form 322`foo=bar`, or just `foo` (the latter implies a boolean option that you want 323to set `true`; it's effectively a shortcut for `foo=true`). 324 325- `sequences` (default: true) -- join consecutive simple statements using the 326 comma operator. May be set to a positive integer to specify the maximum number 327 of consecutive comma sequences that will be generated. If this option is set to 328 `true` then the default `sequences` limit is `200`. Set option to `false` or `0` 329 to disable. The smallest `sequences` length is `2`. A `sequences` value of `1` 330 is grandfathered to be equivalent to `true` and as such means `200`. On rare 331 occasions the default sequences limit leads to very slow compress times in which 332 case a value of `20` or less is recommended. 333 334- `properties` -- rewrite property access using the dot notation, for 335 example `foo["bar"] → foo.bar` 336 337- `dead_code` -- remove unreachable code 338 339- `drop_debugger` -- remove `debugger;` statements 340 341- `unsafe` (default: false) -- apply "unsafe" transformations (discussion below) 342 343- `unsafe_comps` (default: false) -- Reverse `<` and `<=` to `>` and `>=` to 344 allow improved compression. This might be unsafe when an at least one of two 345 operands is an object with computed values due the use of methods like `get`, 346 or `valueOf`. This could cause change in execution order after operands in the 347 comparison are switching. Compression only works if both `comparisons` and 348 `unsafe_comps` are both set to true. 349 350- `unsafe_math` (default: false) -- optimize numerical expressions like 351 `2 * x * 3` into `6 * x`, which may give imprecise floating point results. 352 353- `unsafe_proto` (default: false) -- optimize expressions like 354 `Array.prototype.slice.call(a)` into `[].slice.call(a)` 355 356- `unsafe_regexp` (default: false) -- enable substitutions of variables with 357 `RegExp` values the same way as if they are constants. 358 359- `conditionals` -- apply optimizations for `if`-s and conditional 360 expressions 361 362- `comparisons` -- apply certain optimizations to binary nodes, for example: 363 `!(a <= b) → a > b` (only when `unsafe_comps`), attempts to negate binary 364 nodes, e.g. `a = !b && !c && !d && !e → a=!(b||c||d||e)` etc. 365 366- `evaluate` -- attempt to evaluate constant expressions 367 368- `booleans` -- various optimizations for boolean context, for example `!!a 369 ? b : c → a ? b : c` 370 371- `loops` -- optimizations for `do`, `while` and `for` loops when we can 372 statically determine the condition 373 374- `unused` -- drop unreferenced functions and variables (simple direct variable 375 assignments do not count as references unless set to `"keep_assign"`) 376 377- `toplevel` -- drop unreferenced functions (`"funcs"`) and/or variables (`"vars"`) 378 in the toplevel scope (`false` by default, `true` to drop both unreferenced 379 functions and variables) 380 381- `top_retain` -- prevent specific toplevel functions and variables from `unused` 382 removal (can be array, comma-separated, RegExp or function. Implies `toplevel`) 383 384- `hoist_funs` -- hoist function declarations 385 386- `hoist_vars` (default: false) -- hoist `var` declarations (this is `false` 387 by default because it seems to increase the size of the output in general) 388 389- `if_return` -- optimizations for if/return and if/continue 390 391- `join_vars` -- join consecutive `var` statements 392 393- `cascade` -- small optimization for sequences, transform `x, x` into `x` 394 and `x = something(), x` into `x = something()` 395 396- `collapse_vars` -- Collapse single-use `var` and `const` definitions 397 when possible. 398 399- `reduce_vars` -- Improve optimization on variables assigned with and 400 used as constant values. 401 402- `warnings` -- display warnings when dropping unreachable code or unused 403 declarations etc. 404 405- `negate_iife` -- negate "Immediately-Called Function Expressions" 406 where the return value is discarded, to avoid the parens that the 407 code generator would insert. 408 409- `pure_getters` -- the default is `false`. If you pass `true` for 410 this, UglifyJS will assume that object property access 411 (e.g. `foo.bar` or `foo["bar"]`) doesn't have any side effects. 412 Specify `"strict"` to treat `foo.bar` as side-effect-free only when 413 `foo` is certain to not throw, i.e. not `null` or `undefined`. 414 415- `pure_funcs` -- default `null`. You can pass an array of names and 416 UglifyJS will assume that those functions do not produce side 417 effects. DANGER: will not check if the name is redefined in scope. 418 An example case here, for instance `var q = Math.floor(a/b)`. If 419 variable `q` is not used elsewhere, UglifyJS will drop it, but will 420 still keep the `Math.floor(a/b)`, not knowing what it does. You can 421 pass `pure_funcs: [ 'Math.floor' ]` to let it know that this 422 function won't produce any side effect, in which case the whole 423 statement would get discarded. The current implementation adds some 424 overhead (compression will be slower). 425 426- `drop_console` -- default `false`. Pass `true` to discard calls to 427 `console.*` functions. If you wish to drop a specific function call 428 such as `console.info` and/or retain side effects from function arguments 429 after dropping the function call then use `pure_funcs` instead. 430 431- `expression` -- default `false`. Pass `true` to preserve completion values 432 from terminal statements without `return`, e.g. in bookmarklets. 433 434- `keep_fargs` -- default `true`. Prevents the 435 compressor from discarding unused function arguments. You need this 436 for code which relies on `Function.length`. 437 438- `keep_fnames` -- default `false`. Pass `true` to prevent the 439 compressor from discarding function names. Useful for code relying on 440 `Function.prototype.name`. See also: the `keep_fnames` [mangle option](#mangle). 441 442- `passes` -- default `1`. Number of times to run compress with a maximum of 3. 443 In some cases more than one pass leads to further compressed code. Keep in 444 mind more passes will take more time. 445 446- `keep_infinity` -- default `false`. Pass `true` to prevent `Infinity` from 447 being compressed into `1/0`, which may cause performance issues on Chrome. 448 449- `side_effects` -- default `true`. Pass `false` to disable potentially dropping 450 functions marked as "pure". A function call is marked as "pure" if a comment 451 annotation `/*@__PURE__*/` or `/*#__PURE__*/` immediately precedes the call. For 452 example: `/*@__PURE__*/foo();` 453 454 455### The `unsafe` option 456 457It enables some transformations that *might* break code logic in certain 458contrived cases, but should be fine for most code. You might want to try it 459on your own code, it should reduce the minified size. Here's what happens 460when this flag is on: 461 462- `new Array(1, 2, 3)` or `Array(1, 2, 3)` → `[ 1, 2, 3 ]` 463- `new Object()` → `{}` 464- `String(exp)` or `exp.toString()` → `"" + exp` 465- `new Object/RegExp/Function/Error/Array (...)` → we discard the `new` 466- `typeof foo == "undefined"` → `foo === void 0` 467- `void 0` → `undefined` (if there is a variable named "undefined" in 468 scope; we do it because the variable name will be mangled, typically 469 reduced to a single character) 470 471### Conditional compilation 472 473You can use the `--define` (`-d`) switch in order to declare global 474variables that UglifyJS will assume to be constants (unless defined in 475scope). For example if you pass `--define DEBUG=false` then, coupled with 476dead code removal UglifyJS will discard the following from the output: 477```javascript 478if (DEBUG) { 479 console.log("debug stuff"); 480} 481``` 482 483You can specify nested constants in the form of `--define env.DEBUG=false`. 484 485UglifyJS will warn about the condition being always false and about dropping 486unreachable code; for now there is no option to turn off only this specific 487warning, you can pass `warnings=false` to turn off *all* warnings. 488 489Another way of doing that is to declare your globals as constants in a 490separate file and include it into the build. For example you can have a 491`build/defines.js` file with the following: 492```javascript 493const DEBUG = false; 494const PRODUCTION = true; 495// etc. 496``` 497 498and build your code like this: 499 500 uglifyjs build/defines.js js/foo.js js/bar.js... -c 501 502UglifyJS will notice the constants and, since they cannot be altered, it 503will evaluate references to them to the value itself and drop unreachable 504code as usual. The build will contain the `const` declarations if you use 505them. If you are targeting < ES6 environments which does not support `const`, 506using `var` with `reduce_vars` (enabled by default) should suffice. 507 508<a name="codegen-options"></a> 509 510#### Conditional compilation, API 511You can also use conditional compilation via the programmatic API. With the difference that the 512property name is `global_defs` and is a compressor property: 513 514```js 515uglifyJS.minify([ "input.js"], { 516 compress: { 517 dead_code: true, 518 global_defs: { 519 DEBUG: false 520 } 521 } 522}); 523``` 524 525## Beautifier options 526 527The code generator tries to output shortest code possible by default. In 528case you want beautified output, pass `--beautify` (`-b`). Optionally you 529can pass additional arguments that control the code output: 530 531- `beautify` (default `true`) -- whether to actually beautify the output. 532 Passing `-b` will set this to true, but you might need to pass `-b` even 533 when you want to generate minified code, in order to specify additional 534 arguments, so you can use `-b beautify=false` to override it. 535- `indent-level` (default 4) 536- `indent-start` (default 0) -- prefix all lines by that many spaces 537- `quote-keys` (default `false`) -- pass `true` to quote all keys in literal 538 objects 539- `space-colon` (default `true`) -- insert a space after the colon signs 540- `ascii-only` (default `false`) -- escape Unicode characters in strings and 541 regexps (affects directives with non-ascii characters becoming invalid) 542- `inline-script` (default `false`) -- escape the slash in occurrences of 543 `</script` in strings 544- `width` (default 80) -- only takes effect when beautification is on, this 545 specifies an (orientative) line width that the beautifier will try to 546 obey. It refers to the width of the line text (excluding indentation). 547 It doesn't work very well currently, but it does make the code generated 548 by UglifyJS more readable. 549- `max-line-len` (default 32000) -- maximum line length (for uglified code) 550- `bracketize` (default `false`) -- always insert brackets in `if`, `for`, 551 `do`, `while` or `with` statements, even if their body is a single 552 statement. 553- `semicolons` (default `true`) -- separate statements with semicolons. If 554 you pass `false` then whenever possible we will use a newline instead of a 555 semicolon, leading to more readable output of uglified code (size before 556 gzip could be smaller; size after gzip insignificantly larger). 557- `preamble` (default `null`) -- when passed it must be a string and 558 it will be prepended to the output literally. The source map will 559 adjust for this text. Can be used to insert a comment containing 560 licensing information, for example. 561- `quote_style` (default `0`) -- preferred quote style for strings (affects 562 quoted property names and directives as well): 563 - `0` -- prefers double quotes, switches to single quotes when there are 564 more double quotes in the string itself. 565 - `1` -- always use single quotes 566 - `2` -- always use double quotes 567 - `3` -- always use the original quotes 568- `keep_quoted_props` (default `false`) -- when turned on, prevents stripping 569 quotes from property names in object literals. 570 571### Keeping copyright notices or other comments 572 573You can pass `--comments` to retain certain comments in the output. By 574default it will keep JSDoc-style comments that contain "@preserve", 575"@license" or "@cc_on" (conditional compilation for IE). You can pass 576`--comments all` to keep all the comments, or a valid JavaScript regexp to 577keep only comments that match this regexp. For example `--comments 578'/foo|bar/'` will keep only comments that contain "foo" or "bar". 579 580Note, however, that there might be situations where comments are lost. For 581example: 582```javascript 583function f() { 584 /** @preserve Foo Bar */ 585 function g() { 586 // this function is never called 587 } 588 return something(); 589} 590``` 591 592Even though it has "@preserve", the comment will be lost because the inner 593function `g` (which is the AST node to which the comment is attached to) is 594discarded by the compressor as not referenced. 595 596The safest comments where to place copyright information (or other info that 597needs to be kept in the output) are comments attached to toplevel nodes. 598 599## Support for the SpiderMonkey AST 600 601UglifyJS2 has its own abstract syntax tree format; for 602[practical reasons](http://lisperator.net/blog/uglifyjs-why-not-switching-to-spidermonkey-ast/) 603we can't easily change to using the SpiderMonkey AST internally. However, 604UglifyJS now has a converter which can import a SpiderMonkey AST. 605 606For example [Acorn][acorn] is a super-fast parser that produces a 607SpiderMonkey AST. It has a small CLI utility that parses one file and dumps 608the AST in JSON on the standard output. To use UglifyJS to mangle and 609compress that: 610 611 acorn file.js | uglifyjs --spidermonkey -m -c 612 613The `--spidermonkey` option tells UglifyJS that all input files are not 614JavaScript, but JS code described in SpiderMonkey AST in JSON. Therefore we 615don't use our own parser in this case, but just transform that AST into our 616internal AST. 617 618### Use Acorn for parsing 619 620More for fun, I added the `--acorn` option which will use Acorn to do all 621the parsing. If you pass this option, UglifyJS will `require("acorn")`. 622 623Acorn is really fast (e.g. 250ms instead of 380ms on some 650K code), but 624converting the SpiderMonkey tree that Acorn produces takes another 150ms so 625in total it's a bit more than just using UglifyJS's own parser. 626 627### Using UglifyJS to transform SpiderMonkey AST 628 629Now you can use UglifyJS as any other intermediate tool for transforming 630JavaScript ASTs in SpiderMonkey format. 631 632Example: 633 634```javascript 635function uglify(ast, options, mangle) { 636 // Conversion from SpiderMonkey AST to internal format 637 var uAST = UglifyJS.AST_Node.from_mozilla_ast(ast); 638 639 // Compression 640 uAST.figure_out_scope(); 641 uAST = UglifyJS.Compressor(options).compress(uAST); 642 643 // Mangling (optional) 644 if (mangle) { 645 uAST.figure_out_scope(); 646 uAST.compute_char_frequency(); 647 uAST.mangle_names(); 648 } 649 650 // Back-conversion to SpiderMonkey AST 651 return uAST.to_mozilla_ast(); 652} 653``` 654 655Check out 656[original blog post](http://rreverser.com/using-mozilla-ast-with-uglifyjs/) 657for details. 658 659API Reference 660------------- 661 662Assuming installation via NPM, you can load UglifyJS in your application 663like this: 664```javascript 665var UglifyJS = require("uglify-js"); 666``` 667 668It exports a lot of names, but I'll discuss here the basics that are needed 669for parsing, mangling and compressing a piece of code. The sequence is (1) 670parse, (2) compress, (3) mangle, (4) generate output code. 671 672### The simple way 673 674There's a single toplevel function which combines all the steps. If you 675don't need additional customization, you might want to go with `minify`. 676Example: 677```javascript 678var result = UglifyJS.minify("/path/to/file.js"); 679console.log(result.code); // minified output 680// if you need to pass code instead of file name 681var result = UglifyJS.minify("var b = function () {};", {fromString: true}); 682``` 683 684You can also compress multiple files: 685```javascript 686var result = UglifyJS.minify([ "file1.js", "file2.js", "file3.js" ]); 687console.log(result.code); 688``` 689 690To generate a source map: 691```javascript 692var result = UglifyJS.minify([ "file1.js", "file2.js", "file3.js" ], { 693 outSourceMap: "out.js.map" 694}); 695console.log(result.code); // minified output 696console.log(result.map); 697``` 698 699To generate a source map with the fromString option, you can also use an object: 700```javascript 701var result = UglifyJS.minify({"file1.js": "var a = function () {};"}, { 702 outSourceMap: "out.js.map", 703 outFileName: "out.js", 704 fromString: true 705}); 706``` 707 708Note that the source map is not saved in a file, it's just returned in 709`result.map`. The value passed for `outSourceMap` is only used to set 710`//# sourceMappingURL=out.js.map` in `result.code`. The value of 711`outFileName` is only used to set `file` attribute in source map file. 712 713The `file` attribute in the source map (see [the spec][sm-spec]) will 714use `outFileName` firstly, if it's falsy, then will be deduced from 715`outSourceMap` (by removing `'.map'`). 716 717You can set option `sourceMapInline` to be `true` and source map will 718be appended to code. 719 720You can also specify sourceRoot property to be included in source map: 721```javascript 722var result = UglifyJS.minify([ "file1.js", "file2.js", "file3.js" ], { 723 outSourceMap: "out.js.map", 724 sourceRoot: "http://example.com/src" 725}); 726``` 727 728If you're compressing compiled JavaScript and have a source map for it, you 729can use the `inSourceMap` argument: 730```javascript 731var result = UglifyJS.minify("compiled.js", { 732 inSourceMap: "compiled.js.map", 733 outSourceMap: "minified.js.map" 734}); 735// same as before, it returns `code` and `map` 736``` 737 738If your input source map is not in a file, you can pass it in as an object 739using the `inSourceMap` argument: 740 741```javascript 742var result = UglifyJS.minify("compiled.js", { 743 inSourceMap: JSON.parse(my_source_map_string), 744 outSourceMap: "minified.js.map" 745}); 746``` 747 748The `inSourceMap` is only used if you also request `outSourceMap` (it makes 749no sense otherwise). 750 751To set the source map url, use the `sourceMapUrl` option. 752If you're using the X-SourceMap header instead, you can just set the `sourceMapUrl` option to false. 753Defaults to outSourceMap: 754 755```javascript 756var result = UglifyJS.minify([ "file1.js" ], { 757 outSourceMap: "out.js.map", 758 sourceMapUrl: "localhost/out.js.map" 759}); 760``` 761 762Other options: 763 764- `warnings` (default `false`) — pass `true` to display compressor warnings. 765 766- `fromString` (default `false`) — if you pass `true` then you can pass 767 JavaScript source code, rather than file names. 768 769- `mangle` (default `true`) — pass `false` to skip mangling names, or pass 770 an object to specify mangling options (see below). 771 772- `mangleProperties` (default `false`) — pass an object to specify custom 773 mangle property options. 774 775- `output` (default `null`) — pass an object if you wish to specify 776 additional [output options][codegen]. The defaults are optimized 777 for best compression. 778 779- `compress` (default `{}`) — pass `false` to skip compressing entirely. 780 Pass an object to specify custom [compressor options][compressor]. 781 782- `parse` (default {}) — pass an object if you wish to specify some 783 additional [parser options][parser]. (not all options available... see below) 784 785##### mangle 786 787 - `except` - pass an array of identifiers that should be excluded from mangling 788 789 - `toplevel` — mangle names declared in the toplevel scope (disabled by 790 default). 791 792 - `eval` — mangle names visible in scopes where eval or with are used 793 (disabled by default). 794 795 - `keep_fnames` -- default `false`. Pass `true` to not mangle 796 function names. Useful for code relying on `Function.prototype.name`. 797 See also: the `keep_fnames` [compress option](#compressor-options). 798 799 Examples: 800 801 ```javascript 802 //tst.js 803 var globalVar; 804 function funcName(firstLongName, anotherLongName) 805 { 806 var myVariable = firstLongName + anotherLongName; 807 } 808 809 UglifyJS.minify("tst.js").code; 810 // 'function funcName(a,n){}var globalVar;' 811 812 UglifyJS.minify("tst.js", { mangle: { except: ['firstLongName'] } }).code; 813 // 'function funcName(firstLongName,a){}var globalVar;' 814 815 UglifyJS.minify("tst.js", { mangle: { toplevel: true } }).code; 816 // 'function n(n,a){}var a;' 817 ``` 818 819##### mangleProperties options 820 821 - `regex` — Pass a RegExp to only mangle certain names (maps to the `--mangle-regex` CLI arguments option) 822 - `ignore_quoted` – Only mangle unquoted property names (maps to the `--mangle-props 2` CLI arguments option) 823 - `debug` – Mangle names with the original name still present (maps to the `--mangle-props-debug` CLI arguments option). Defaults to `false`. Pass an empty string to enable, or a non-empty string to set the suffix. 824 825We could add more options to `UglifyJS.minify` — if you need additional 826functionality please suggest! 827 828### The hard way 829 830Following there's more detailed API info, in case the `minify` function is 831too simple for your needs. 832 833#### The parser 834```javascript 835var toplevel_ast = UglifyJS.parse(code, options); 836``` 837 838`options` is optional and if present it must be an object. The following 839properties are available: 840 841- `strict` — disable automatic semicolon insertion and support for trailing 842 comma in arrays and objects 843- `bare_returns` — Allow return outside of functions. (maps to the 844 `--bare-returns` CLI arguments option and available to `minify` `parse` 845 other options object) 846- `filename` — the name of the file where this code is coming from 847- `toplevel` — a `toplevel` node (as returned by a previous invocation of 848 `parse`) 849 850The last two options are useful when you'd like to minify multiple files and 851get a single file as the output and a proper source map. Our CLI tool does 852something like this: 853```javascript 854var toplevel = null; 855files.forEach(function(file){ 856 var code = fs.readFileSync(file, "utf8"); 857 toplevel = UglifyJS.parse(code, { 858 filename: file, 859 toplevel: toplevel 860 }); 861}); 862``` 863 864After this, we have in `toplevel` a big AST containing all our files, with 865each token having proper information about where it came from. 866 867#### Scope information 868 869UglifyJS contains a scope analyzer that you need to call manually before 870compressing or mangling. Basically it augments various nodes in the AST 871with information about where is a name defined, how many times is a name 872referenced, if it is a global or not, if a function is using `eval` or the 873`with` statement etc. I will discuss this some place else, for now what's 874important to know is that you need to call the following before doing 875anything with the tree: 876```javascript 877toplevel.figure_out_scope() 878``` 879 880#### Compression 881 882Like this: 883```javascript 884var compressor = UglifyJS.Compressor(options); 885var compressed_ast = compressor.compress(toplevel); 886``` 887 888The `options` can be missing. Available options are discussed above in 889“Compressor options”. Defaults should lead to best compression in most 890scripts. 891 892The compressor is destructive, so don't rely that `toplevel` remains the 893original tree. 894 895#### Mangling 896 897After compression it is a good idea to call again `figure_out_scope` (since 898the compressor might drop unused variables / unreachable code and this might 899change the number of identifiers or their position). Optionally, you can 900call a trick that helps after Gzip (counting character frequency in 901non-mangleable words). Example: 902```javascript 903compressed_ast.figure_out_scope(); 904compressed_ast.compute_char_frequency(); 905compressed_ast.mangle_names(); 906``` 907 908#### Generating output 909 910AST nodes have a `print` method that takes an output stream. Essentially, 911to generate code you do this: 912```javascript 913var stream = UglifyJS.OutputStream(options); 914compressed_ast.print(stream); 915var code = stream.toString(); // this is your minified code 916``` 917 918or, for a shortcut you can do: 919```javascript 920var code = compressed_ast.print_to_string(options); 921``` 922 923As usual, `options` is optional. The output stream accepts a lot of options, 924most of them documented above in section “Beautifier options”. The two 925which we care about here are `source_map` and `comments`. 926 927#### Keeping comments in the output 928 929In order to keep certain comments in the output you need to pass the 930`comments` option. Pass a RegExp (as string starting and closing with `/` 931or pass a RegExp object), a boolean or a function. Stringified options 932`all` and `some` can be passed too, where `some` behaves like it's cli 933equivalent `--comments` without passing a value. If you pass a RegExp, 934only those comments whose body matches the RegExp will be kept. Note that body 935means without the initial `//` or `/*`. If you pass a function, it will be 936called for every comment in the tree and will receive two arguments: the 937node that the comment is attached to, and the comment token itself. 938 939The comment token has these properties: 940 941- `type`: "comment1" for single-line comments or "comment2" for multi-line 942 comments 943- `value`: the comment body 944- `pos` and `endpos`: the start/end positions (zero-based indexes) in the 945 original code where this comment appears 946- `line` and `col`: the line and column where this comment appears in the 947 original code 948- `file` — the file name of the original file 949- `nlb` — true if there was a newline before this comment in the original 950 code, or if this comment contains a newline. 951 952Your function should return `true` to keep the comment, or a falsy value 953otherwise. 954 955#### Generating a source mapping 956 957You need to pass the `source_map` argument when calling `print`. It needs 958to be a `SourceMap` object (which is a thin wrapper on top of the 959[source-map][source-map] library). 960 961Example: 962```javascript 963var source_map = UglifyJS.SourceMap(source_map_options); 964var stream = UglifyJS.OutputStream({ 965 ... 966 source_map: source_map 967}); 968compressed_ast.print(stream); 969 970var code = stream.toString(); 971var map = source_map.toString(); // json output for your source map 972``` 973 974The `source_map_options` (optional) can contain the following properties: 975 976- `file`: the name of the JavaScript output file that this mapping refers to 977- `root`: the `sourceRoot` property (see the [spec][sm-spec]) 978- `orig`: the "original source map", handy when you compress generated JS 979 and want to map the minified output back to the original code where it 980 came from. It can be simply a string in JSON, or a JSON object containing 981 the original source map. 982 983 [acorn]: https://github.com/ternjs/acorn 984 [source-map]: https://github.com/mozilla/source-map 985 [sm-spec]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit 986 [codegen]: http://lisperator.net/uglifyjs/codegen 987 [compressor]: http://lisperator.net/uglifyjs/compress 988 [parser]: http://lisperator.net/uglifyjs/parser 989 990#### Support for `const` 991 992`const` in `uglify-js@2.x` has function scope and as such behaves much like 993`var` - unlike `const` in ES2015 (ES6) which has block scope. It is recommended 994to avoid using `const` for this reason as it will have undefined behavior when 995run on an ES2015 compatible browser. 996