source: frontend/node_modules/terser/README.md

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 12 days ago

Fix frontend appearance

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