adj-ordinaryjs 0.0.1-security → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of adj-ordinaryjs might be problematic. Click here for more details.

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