UNPKG

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