source: imaps-frontend/node_modules/terser/README.md

main
Last change on this file was 79a0317, checked in by stefan toskovski <stefantoska84@…>, 4 days ago

F4 Finalna Verzija

  • Property mode set to 100644
File size: 59.1 KB
RevLine 
[79a0317]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][sm-spec])
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- `evaluate` (default: `true`) -- attempt to evaluate constant expressions
744
745- `expression` (default: `false`) -- Pass `true` to preserve completion values
746 from terminal statements without `return`, e.g. in bookmarklets.
747
748- `global_defs` (default: `{}`) -- see [conditional compilation](#conditional-compilation)
749
750- `hoist_funs` (default: `false`) -- hoist function declarations
751
752- `hoist_props` (default: `true`) -- hoist properties from constant object and
753 array literals into regular variables subject to a set of constraints. For example:
754 `var o={p:1, q:2}; f(o.p, o.q);` is converted to `f(1, 2);`. Note: `hoist_props`
755 works best with `mangle` enabled, the `compress` option `passes` set to `2` or higher,
756 and the `compress` option `toplevel` enabled.
757
758- `hoist_vars` (default: `false`) -- hoist `var` declarations (this is `false`
759 by default because it seems to increase the size of the output in general)
760
761- `if_return` (default: `true`) -- optimizations for if/return and if/continue
762
763- `inline` (default: `true`) -- inline calls to function with simple/`return` statement:
764 - `false` -- same as `0`
765 - `0` -- disabled inlining
766 - `1` -- inline simple functions
767 - `2` -- inline functions with arguments
768 - `3` -- inline functions with arguments and variables
769 - `true` -- same as `3`
770
771- `join_vars` (default: `true`) -- join consecutive `var`, `let` and `const` statements
772
773- `keep_classnames` (default: `false`) -- Pass `true` to prevent the compressor from
774 discarding class names. Pass a regular expression to only keep class names matching
775 that regex. See also: the `keep_classnames` [mangle option](#mangle-options).
776
777- `keep_fargs` (default: `true`) -- Prevents the compressor from discarding unused
778 function arguments. You need this for code which relies on `Function.length`.
779
780- `keep_fnames` (default: `false`) -- Pass `true` to prevent the
781 compressor from discarding function names. Pass a regular expression to only keep
782 function names matching that regex. Useful for code relying on `Function.prototype.name`.
783 See also: the `keep_fnames` [mangle option](#mangle-options).
784
785- `keep_infinity` (default: `false`) -- Pass `true` to prevent `Infinity` from
786 being compressed into `1/0`, which may cause performance issues on Chrome.
787
788- `lhs_constants` (default: `true`) -- Moves constant values to the left-hand side
789 of binary nodes. `foo == 42 → 42 == foo`
790
791- `loops` (default: `true`) -- optimizations for `do`, `while` and `for` loops
792 when we can statically determine the condition.
793
794- `module` (default `false`) -- Pass `true` when compressing an ES6 module. Strict
795 mode is implied and the `toplevel` option as well.
796
797- `negate_iife` (default: `true`) -- negate "Immediately-Called Function Expressions"
798 where the return value is discarded, to avoid the parens that the
799 code generator would insert.
800
801- `passes` (default: `1`) -- The maximum number of times to run compress.
802 In some cases more than one pass leads to further compressed code. Keep in
803 mind more passes will take more time.
804
805- `properties` (default: `true`) -- rewrite property access using the dot notation, for
806 example `foo["bar"] → foo.bar`
807
808- `pure_funcs` (default: `null`) -- You can pass an array of names and
809 Terser will assume that those functions do not produce side
810 effects. DANGER: will not check if the name is redefined in scope.
811 An example case here, for instance `var q = Math.floor(a/b)`. If
812 variable `q` is not used elsewhere, Terser will drop it, but will
813 still keep the `Math.floor(a/b)`, not knowing what it does. You can
814 pass `pure_funcs: [ 'Math.floor' ]` to let it know that this
815 function won't produce any side effect, in which case the whole
816 statement would get discarded. The current implementation adds some
817 overhead (compression will be slower).
818
819- `pure_getters` (default: `"strict"`) -- If you pass `true` for
820 this, Terser will assume that object property access
821 (e.g. `foo.bar` or `foo["bar"]`) doesn't have any side effects.
822 Specify `"strict"` to treat `foo.bar` as side-effect-free only when
823 `foo` is certain to not throw, i.e. not `null` or `undefined`.
824
825- `pure_new` (default: `false`) -- Set to `true` to assume `new X()` never has
826 side effects.
827
828- `reduce_vars` (default: `true`) -- Improve optimization on variables assigned with and
829 used as constant values.
830
831- `reduce_funcs` (default: `true`) -- Inline single-use functions when
832 possible. Depends on `reduce_vars` being enabled. Disabling this option
833 sometimes improves performance of the output code.
834
835- `sequences` (default: `true`) -- join consecutive simple statements using the
836 comma operator. May be set to a positive integer to specify the maximum number
837 of consecutive comma sequences that will be generated. If this option is set to
838 `true` then the default `sequences` limit is `200`. Set option to `false` or `0`
839 to disable. The smallest `sequences` length is `2`. A `sequences` value of `1`
840 is grandfathered to be equivalent to `true` and as such means `200`. On rare
841 occasions the default sequences limit leads to very slow compress times in which
842 case a value of `20` or less is recommended.
843
844- `side_effects` (default: `true`) -- Remove expressions which have no side effects
845 and whose results aren't used.
846
847- `switches` (default: `true`) -- de-duplicate and remove unreachable `switch` branches
848
849- `toplevel` (default: `false`) -- drop unreferenced functions (`"funcs"`) and/or
850 variables (`"vars"`) in the top level scope (`false` by default, `true` to drop
851 both unreferenced functions and variables)
852
853- `top_retain` (default: `null`) -- prevent specific toplevel functions and
854 variables from `unused` removal (can be array, comma-separated, RegExp or
855 function. Implies `toplevel`)
856
857- `typeofs` (default: `true`) -- Transforms `typeof foo == "undefined"` into
858 `foo === void 0`. Note: recommend to set this value to `false` for IE10 and
859 earlier versions due to known issues.
860
861- `unsafe` (default: `false`) -- apply "unsafe" transformations
862 ([details](#the-unsafe-compress-option)).
863
864- `unsafe_arrows` (default: `false`) -- Convert ES5 style anonymous function
865 expressions to arrow functions if the function body does not reference `this`.
866 Note: it is not always safe to perform this conversion if code relies on the
867 the function having a `prototype`, which arrow functions lack.
868 This transform requires that the `ecma` compress option is set to `2015` or greater.
869
870- `unsafe_comps` (default: `false`) -- Reverse `<` and `<=` to `>` and `>=` to
871 allow improved compression. This might be unsafe when an at least one of two
872 operands is an object with computed values due the use of methods like `get`,
873 or `valueOf`. This could cause change in execution order after operands in the
874 comparison are switching. Compression only works if both `comparisons` and
875 `unsafe_comps` are both set to true.
876
877- `unsafe_Function` (default: `false`) -- compress and mangle `Function(args, code)`
878 when both `args` and `code` are string literals.
879
880- `unsafe_math` (default: `false`) -- optimize numerical expressions like
881 `2 * x * 3` into `6 * x`, which may give imprecise floating point results.
882
883- `unsafe_symbols` (default: `false`) -- removes keys from native Symbol
884 declarations, e.g `Symbol("kDog")` becomes `Symbol()`.
885
886- `unsafe_methods` (default: false) -- Converts `{ m: function(){} }` to
887 `{ m(){} }`. `ecma` must be set to `6` or greater to enable this transform.
888 If `unsafe_methods` is a RegExp then key/value pairs with keys matching the
889 RegExp will be converted to concise methods.
890 Note: if enabled there is a risk of getting a "`<method name>` is not a
891 constructor" TypeError should any code try to `new` the former function.
892
893- `unsafe_proto` (default: `false`) -- optimize expressions like
894 `Array.prototype.slice.call(a)` into `[].slice.call(a)`
895
896- `unsafe_regexp` (default: `false`) -- enable substitutions of variables with
897 `RegExp` values the same way as if they are constants.
898
899- `unsafe_undefined` (default: `false`) -- substitute `void 0` if there is a
900 variable named `undefined` in scope (variable name will be mangled, typically
901 reduced to a single character)
902
903- `unused` (default: `true`) -- drop unreferenced functions and variables (simple
904 direct variable assignments do not count as references unless set to `"keep_assign"`)
905
906## Mangle options
907
908- `eval` (default `false`) -- Pass `true` to mangle names visible in scopes
909 where `eval` or `with` are used.
910
911- `keep_classnames` (default `false`) -- Pass `true` to not mangle class names.
912 Pass a regular expression to only keep class names matching that regex.
913 See also: the `keep_classnames` [compress option](#compress-options).
914
915- `keep_fnames` (default `false`) -- Pass `true` to not mangle function names.
916 Pass a regular expression to only keep function names matching that regex.
917 Useful for code relying on `Function.prototype.name`. See also: the `keep_fnames`
918 [compress option](#compress-options).
919
920- `module` (default `false`) -- Pass `true` an ES6 modules, where the toplevel
921 scope is not the global scope. Implies `toplevel` and assumes input code is strict mode JS.
922
923- `nth_identifier` (default: an internal mangler that weights based on character
924 frequency analysis) -- Pass an object with a `get(n)` function that converts an
925 ordinal into the nth most favored (usually shortest) identifier.
926 Optionally also provide `reset()`, `sort()`, and `consider(chars, delta)` to
927 use character frequency analysis of the source code.
928
929- `reserved` (default `[]`) -- Pass an array of identifiers that should be
930 excluded from mangling. Example: `["foo", "bar"]`.
931
932- `toplevel` (default `false`) -- Pass `true` to mangle names declared in the
933 top level scope.
934
935- `safari10` (default `false`) -- Pass `true` to work around the Safari 10 loop
936 iterator [bug](https://bugs.webkit.org/show_bug.cgi?id=171041)
937 "Cannot declare a let variable twice".
938 See also: the `safari10` [format option](#format-options).
939
940Examples:
941
942```javascript
943// test.js
944var globalVar;
945function funcName(firstLongName, anotherLongName) {
946 var myVariable = firstLongName + anotherLongName;
947}
948```
949```javascript
950var code = fs.readFileSync("test.js", "utf8");
951
952await minify(code).code;
953// 'function funcName(a,n){}var globalVar;'
954
955await minify(code, { mangle: { reserved: ['firstLongName'] } }).code;
956// 'function funcName(firstLongName,a){}var globalVar;'
957
958await minify(code, { mangle: { toplevel: true } }).code;
959// 'function n(n,a){}var a;'
960```
961
962### Mangle properties options
963
964- `builtins` (default: `false`) — Use `true` to allow the mangling of builtin
965 DOM properties. Not recommended to override this setting.
966
967- `debug` (default: `false`) — Mangle names with the original name still present.
968 Pass an empty string `""` to enable, or a non-empty string to set the debug suffix.
969
970- `keep_quoted` (default: `false`) — How quoting properties (`{"prop": ...}` and `obj["prop"]`) controls what gets mangled.
971 - `"strict"` (recommended) -- `obj.prop` is mangled.
972 - `false` -- `obj["prop"]` is mangled.
973 - `true` -- `obj.prop` is mangled unless there is `obj["prop"]` elsewhere in the code.
974
975- `nth_identifier` (default: an internal mangler that weights based on character
976 frequency analysis) -- Pass an object with a `get(n)` function that converts an
977 ordinal into the nth most favored (usually shortest) identifier.
978 Optionally also provide `reset()`, `sort()`, and `consider(chars, delta)` to
979 use character frequency analysis of the source code.
980
981- `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.
982
983- `reserved` (default: `[]`) — Do not mangle property names listed in the
984 `reserved` array.
985
986- `undeclared` (default: `false`) - Mangle those names when they are accessed
987 as properties of known top level variables but their declarations are never
988 found in input code. May be useful when only minifying parts of a project.
989 See [#397](https://github.com/terser/terser/issues/397) for more details.
990
991
992## Format options
993
994These options control the format of Terser's output code. Previously known
995as "output options".
996
997- `ascii_only` (default `false`) -- escape Unicode characters in strings and
998 regexps (affects directives with non-ascii characters becoming invalid)
999
1000- `beautify` (default `false`) -- (DEPRECATED) whether to beautify the output.
1001 When using the legacy `-b` CLI flag, this is set to true by default.
1002
1003- `braces` (default `false`) -- always insert braces in `if`, `for`,
1004 `do`, `while` or `with` statements, even if their body is a single
1005 statement.
1006
1007- `comments` (default `"some"`) -- by default it keeps JSDoc-style comments
1008 that contain "@license", "@copyright", "@preserve" or start with `!`, pass `true`
1009 or `"all"` to preserve all comments, `false` to omit comments in the output,
1010 a regular expression string (e.g. `/^!/`) or a function.
1011
1012- `ecma` (default `5`) -- set desired EcmaScript standard version for output.
1013 Set `ecma` to `2015` or greater to emit shorthand object properties - i.e.:
1014 `{a}` instead of `{a: a}`. The `ecma` option will only change the output in
1015 direct control of the beautifier. Non-compatible features in your input will
1016 still be output as is. For example: an `ecma` setting of `5` will **not**
1017 convert modern code to ES5.
1018
1019- `indent_level` (default `4`)
1020
1021- `indent_start` (default `0`) -- prefix all lines by that many spaces
1022
1023- `inline_script` (default `true`) -- escape HTML comments and the slash in
1024 occurrences of `</script>` in strings
1025
1026- `keep_numbers` (default `false`) -- keep number literals as it was in original code
1027 (disables optimizations like converting `1000000` into `1e6`)
1028
1029- `keep_quoted_props` (default `false`) -- when turned on, prevents stripping
1030 quotes from property names in object literals.
1031
1032- `max_line_len` (default `false`) -- maximum line length (for minified code)
1033
1034- `preamble` (default `null`) -- when passed it must be a string and
1035 it will be prepended to the output literally. The source map will
1036 adjust for this text. Can be used to insert a comment containing
1037 licensing information, for example.
1038
1039- `quote_keys` (default `false`) -- pass `true` to quote all keys in literal
1040 objects
1041
1042- `quote_style` (default `0`) -- preferred quote style for strings (affects
1043 quoted property names and directives as well):
1044 - `0` -- prefers double quotes, switches to single quotes when there are
1045 more double quotes in the string itself. `0` is best for gzip size.
1046 - `1` -- always use single quotes
1047 - `2` -- always use double quotes
1048 - `3` -- always use the original quotes
1049
1050- `preserve_annotations` -- (default `false`) -- Preserve [Terser annotations](#annotations) in the output.
1051
1052- `safari10` (default `false`) -- set this option to `true` to work around
1053 the [Safari 10/11 await bug](https://bugs.webkit.org/show_bug.cgi?id=176685).
1054 See also: the `safari10` [mangle option](#mangle-options).
1055
1056- `semicolons` (default `true`) -- separate statements with semicolons. If
1057 you pass `false` then whenever possible we will use a newline instead of a
1058 semicolon, leading to more readable output of minified code (size before
1059 gzip could be smaller; size after gzip insignificantly larger).
1060
1061- `shebang` (default `true`) -- preserve shebang `#!` in preamble (bash scripts)
1062
1063- `spidermonkey` (default `false`) -- produce a Spidermonkey (Mozilla) AST
1064
1065- `webkit` (default `false`) -- enable workarounds for WebKit bugs.
1066 PhantomJS users should set this option to `true`.
1067
1068- `wrap_iife` (default `false`) -- pass `true` to wrap immediately invoked
1069 function expressions. See
1070 [#640](https://github.com/mishoo/UglifyJS2/issues/640) for more details.
1071
1072- `wrap_func_args` (default `true`) -- pass `false` if you do not want to wrap
1073 function expressions that are passed as arguments, in parenthesis. See
1074 [OptimizeJS](https://github.com/nolanlawson/optimize-js) for more details.
1075
1076
1077<!-- OPTIONS:END -->
1078
1079
1080# Miscellaneous
1081
1082<!-- MISCELLANEOUS:START -->
1083
1084### Keeping copyright notices or other comments
1085
1086You can pass `--comments` to retain certain comments in the output. By
1087default it will keep comments starting with "!" and JSDoc-style comments that
1088contain "@preserve", "@copyright", "@license" or "@cc_on" (conditional compilation for IE).
1089You can pass `--comments all` to keep all the comments, or a valid JavaScript regexp to
1090keep only comments that match this regexp. For example `--comments /^!/`
1091will keep comments like `/*! Copyright Notice */`.
1092
1093Note, however, that there might be situations where comments are lost. For
1094example:
1095```javascript
1096function f() {
1097 /** @preserve Foo Bar */
1098 function g() {
1099 // this function is never called
1100 }
1101 return something();
1102}
1103```
1104
1105Even though it has "@preserve", the comment will be lost because the inner
1106function `g` (which is the AST node to which the comment is attached to) is
1107discarded by the compressor as not referenced.
1108
1109The safest comments where to place copyright information (or other info that
1110needs to be kept in the output) are comments attached to toplevel nodes.
1111
1112### The `unsafe` `compress` option
1113
1114It enables some transformations that *might* break code logic in certain
1115contrived cases, but should be fine for most code. It assumes that standard
1116built-in ECMAScript functions and classes have not been altered or replaced.
1117You might want to try it on your own code; it should reduce the minified size.
1118Some examples of the optimizations made when this option is enabled:
1119
1120- `new Array(1, 2, 3)` or `Array(1, 2, 3)` → `[ 1, 2, 3 ]`
1121- `Array.from([1, 2, 3])` → `[1, 2, 3]`
1122- `new Object()` → `{}`
1123- `String(exp)` or `exp.toString()` → `"" + exp`
1124- `new Object/RegExp/Function/Error/Array (...)` → we discard the `new`
1125- `"foo bar".substr(4)` → `"bar"`
1126
1127### Conditional compilation
1128
1129You can use the `--define` (`-d`) switch in order to declare global
1130variables that Terser will assume to be constants (unless defined in
1131scope). For example if you pass `--define DEBUG=false` then, coupled with
1132dead code removal Terser will discard the following from the output:
1133```javascript
1134if (DEBUG) {
1135 console.log("debug stuff");
1136}
1137```
1138
1139You can specify nested constants in the form of `--define env.DEBUG=false`.
1140
1141Another way of doing that is to declare your globals as constants in a
1142separate file and include it into the build. For example you can have a
1143`build/defines.js` file with the following:
1144```javascript
1145var DEBUG = false;
1146var PRODUCTION = true;
1147// etc.
1148```
1149
1150and build your code like this:
1151
1152 terser build/defines.js js/foo.js js/bar.js... -c
1153
1154Terser will notice the constants and, since they cannot be altered, it
1155will evaluate references to them to the value itself and drop unreachable
1156code as usual. The build will contain the `const` declarations if you use
1157them. If you are targeting < ES6 environments which does not support `const`,
1158using `var` with `reduce_vars` (enabled by default) should suffice.
1159
1160### Conditional compilation API
1161
1162You can also use conditional compilation via the programmatic API. With the difference that the
1163property name is `global_defs` and is a compressor property:
1164
1165```javascript
1166var result = await minify(fs.readFileSync("input.js", "utf8"), {
1167 compress: {
1168 dead_code: true,
1169 global_defs: {
1170 DEBUG: false
1171 }
1172 }
1173});
1174```
1175
1176To replace an identifier with an arbitrary non-constant expression it is
1177necessary to prefix the `global_defs` key with `"@"` to instruct Terser
1178to parse the value as an expression:
1179```javascript
1180await minify("alert('hello');", {
1181 compress: {
1182 global_defs: {
1183 "@alert": "console.log"
1184 }
1185 }
1186}).code;
1187// returns: 'console.log("hello");'
1188```
1189
1190Otherwise it would be replaced as string literal:
1191```javascript
1192await minify("alert('hello');", {
1193 compress: {
1194 global_defs: {
1195 "alert": "console.log"
1196 }
1197 }
1198}).code;
1199// returns: '"console.log"("hello");'
1200```
1201
1202### Annotations
1203
1204Annotations in Terser are a way to tell it to treat a certain function call differently. The following annotations are available:
1205
1206 * `/*@__INLINE__*/` - forces a function to be inlined somewhere.
1207 * `/*@__NOINLINE__*/` - Makes sure the called function is not inlined into the call site.
1208 * `/*@__PURE__*/` - Marks a function call as pure. That means, it can safely be dropped.
1209 * `/*@__KEY__*/` - Marks a string literal as a property to also mangle it when mangling properties.
1210 * `/*@__MANGLE_PROP__*/` - Opts-in an object property (or class field) for mangling, when the property mangler is enabled.
1211
1212You can use either a `@` sign at the start, or a `#`.
1213
1214Here are some examples on how to use them:
1215
1216```javascript
1217/*@__INLINE__*/
1218function_always_inlined_here()
1219
1220/*#__NOINLINE__*/
1221function_cant_be_inlined_into_here()
1222
1223const x = /*#__PURE__*/i_am_dropped_if_x_is_not_used()
1224
1225function lookup(object, key) { return object[key]; }
1226lookup({ i_will_be_mangled_too: "bar" }, /*@__KEY__*/ "i_will_be_mangled_too");
1227```
1228
1229### ESTree / SpiderMonkey AST
1230
1231Terser has its own abstract syntax tree format; for
1232[practical reasons](http://lisperator.net/blog/uglifyjs-why-not-switching-to-spidermonkey-ast/)
1233we can't easily change to using the SpiderMonkey AST internally. However,
1234Terser now has a converter which can import a SpiderMonkey AST.
1235
1236For example [Acorn][acorn] is a super-fast parser that produces a
1237SpiderMonkey AST. It has a small CLI utility that parses one file and dumps
1238the AST in JSON on the standard output. To use Terser to mangle and
1239compress that:
1240
1241 acorn file.js | terser -p spidermonkey -m -c
1242
1243The `-p spidermonkey` option tells Terser that all input files are not
1244JavaScript, but JS code described in SpiderMonkey AST in JSON. Therefore we
1245don't use our own parser in this case, but just transform that AST into our
1246internal AST.
1247
1248`spidermonkey` is also available in `minify` as `parse` and `format` options to
1249accept and/or produce a spidermonkey AST.
1250
1251### Use Acorn for parsing
1252
1253More for fun, I added the `-p acorn` option which will use Acorn to do all
1254the parsing. If you pass this option, Terser will `require("acorn")`.
1255
1256Acorn is really fast (e.g. 250ms instead of 380ms on some 650K code), but
1257converting the SpiderMonkey tree that Acorn produces takes another 150ms so
1258in total it's a bit more than just using Terser's own parser.
1259
1260[acorn]: https://github.com/ternjs/acorn
1261[sm-spec]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k
1262
1263### Terser Fast Minify Mode
1264
1265It's not well known, but whitespace removal and symbol mangling accounts
1266for 95% of the size reduction in minified code for most JavaScript - not
1267elaborate code transforms. One can simply disable `compress` to speed up
1268Terser builds by 3 to 4 times.
1269
1270| d3.js | size | gzip size | time (s) |
1271| --- | ---: | ---: | ---: |
1272| original | 451,131 | 108,733 | - |
1273| terser@3.7.5 mangle=false, compress=false | 316,600 | 85,245 | 0.82 |
1274| terser@3.7.5 mangle=true, compress=false | 220,216 | 72,730 | 1.45 |
1275| terser@3.7.5 mangle=true, compress=true | 212,046 | 70,954 | 5.87 |
1276| babili@0.1.4 | 210,713 | 72,140 | 12.64 |
1277| babel-minify@0.4.3 | 210,321 | 72,242 | 48.67 |
1278| babel-minify@0.5.0-alpha.01eac1c3 | 210,421 | 72,238 | 14.17 |
1279
1280To enable fast minify mode from the CLI use:
1281```
1282terser file.js -m
1283```
1284To enable fast minify mode with the API use:
1285```js
1286await minify(code, { compress: false, mangle: true });
1287```
1288
1289#### Source maps and debugging
1290
1291Various `compress` transforms that simplify, rearrange, inline and remove code
1292are known to have an adverse effect on debugging with source maps. This is
1293expected as code is optimized and mappings are often simply not possible as
1294some code no longer exists. For highest fidelity in source map debugging
1295disable the `compress` option and just use `mangle`.
1296
1297When debugging, make sure you enable the **"map scopes"** feature to map mangled variable names back to their original names.
1298Without this, all variable values will be `undefined`. See https://github.com/terser/terser/issues/1367 for more details.
1299<br/><br/>
1300
1301![image](https://user-images.githubusercontent.com/27283110/230441652-ac5cf6b0-5dc5-4ffc-9d8b-bd02875484f4.png)
1302
1303### Compiler assumptions
1304
1305To allow for better optimizations, the compiler makes various assumptions:
1306
1307- `.toString()` and `.valueOf()` don't have side effects, and for built-in
1308 objects they have not been overridden.
1309- `undefined`, `NaN` and `Infinity` have not been externally redefined.
1310- `arguments.callee`, `arguments.caller` and `Function.prototype.caller` are not used.
1311- The code doesn't expect the contents of `Function.prototype.toString()` or
1312 `Error.prototype.stack` to be anything in particular.
1313- Getting and setting properties on a plain object does not cause other side effects
1314 (using `.watch()` or `Proxy`).
1315- Object properties can be added, removed and modified (not prevented with
1316 `Object.defineProperty()`, `Object.defineProperties()`, `Object.freeze()`,
1317 `Object.preventExtensions()` or `Object.seal()`).
1318- `document.all` is not `== null`
1319- Assigning properties to a class doesn't have side effects and does not throw.
1320
1321### Build Tools and Adaptors using Terser
1322
1323https://www.npmjs.com/browse/depended/terser
1324
1325### Replacing `uglify-es` with `terser` in a project using `yarn`
1326
1327A number of JS bundlers and uglify wrappers are still using buggy versions
1328of `uglify-es` and have not yet upgraded to `terser`. If you are using `yarn`
1329you can add the following alias to your project's `package.json` file:
1330
1331```js
1332 "resolutions": {
1333 "uglify-es": "npm:terser"
1334 }
1335```
1336
1337to use `terser` instead of `uglify-es` in all deeply nested dependencies
1338without changing any code.
1339
1340Note: for this change to take effect you must run the following commands
1341to remove the existing `yarn` lock file and reinstall all packages:
1342
1343```
1344$ rm -rf node_modules yarn.lock
1345$ yarn
1346```
1347
1348<!-- MISCELLANEOUS:END -->
1349
1350# Reporting issues
1351
1352<!-- REPORTING_ISSUES:START -->
1353
1354## A minimal, reproducible example
1355
1356You're expected to provide a [minimal reproducible example] of input code that will demonstrate your issue.
1357
1358To get to this example, you can remove bits of your code and stop if your issue ceases to reproduce.
1359
1360## Obtaining the source code given to Terser
1361
1362Because 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.
1363
1364These logs will contain the input code and options of each `minify()` call.
1365
1366```bash
1367TERSER_DEBUG_DIR=/tmp/terser-log-dir command-that-uses-terser
1368ls /tmp/terser-log-dir
1369terser-debug-123456.log
1370```
1371
1372If 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:
1373
1374```
1375> npx cross-env TERSER_DEBUG_DIR=/path/to/logs command-that-uses-terser
1376```
1377
1378## Stack traces
1379
1380In 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.
1381
1382<!-- REPORTING_ISSUES:END -->
1383
1384# README.md Patrons:
1385
1386*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.
1387
1388These are the second-tier patrons. Great thanks for your support!
1389
1390 * CKEditor ![](https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/15452278/f8548dcf48d740619071e8d614459280/1?token-time=2145916800&token-hash=SIQ54PhIPHv3M7CVz9LxS8_8v4sOw4H304HaXsXj8MM%3D)
1391 * 38elements ![](https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/12501844/88e7fc5dd62d45c6a5626533bbd48cfb/1?token-time=2145916800&token-hash=c3AsQ5T0IQWic0zKxFHu-bGGQJkXQFvafvJ4bPerFR4%3D)
1392
1393## Contributors
1394
1395### Code Contributors
1396
1397This project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].
1398<a href="https://github.com/terser/terser/graphs/contributors"><img src="https://opencollective.com/terser/contributors.svg?width=890&button=false" /></a>
1399
1400### Financial Contributors
1401
1402Become a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/terser/contribute)]
1403
1404#### Individuals
1405
1406<a href="https://opencollective.com/terser"><img src="https://opencollective.com/terser/individuals.svg?width=890"></a>
1407
1408#### Organizations
1409
1410Support this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/terser/contribute)]
1411
1412<a href="https://opencollective.com/terser/organization/0/website"><img src="https://opencollective.com/terser/organization/0/avatar.svg"></a>
1413<a href="https://opencollective.com/terser/organization/1/website"><img src="https://opencollective.com/terser/organization/1/avatar.svg"></a>
1414<a href="https://opencollective.com/terser/organization/2/website"><img src="https://opencollective.com/terser/organization/2/avatar.svg"></a>
1415<a href="https://opencollective.com/terser/organization/3/website"><img src="https://opencollective.com/terser/organization/3/avatar.svg"></a>
1416<a href="https://opencollective.com/terser/organization/4/website"><img src="https://opencollective.com/terser/organization/4/avatar.svg"></a>
1417<a href="https://opencollective.com/terser/organization/5/website"><img src="https://opencollective.com/terser/organization/5/avatar.svg"></a>
1418<a href="https://opencollective.com/terser/organization/6/website"><img src="https://opencollective.com/terser/organization/6/avatar.svg"></a>
1419<a href="https://opencollective.com/terser/organization/7/website"><img src="https://opencollective.com/terser/organization/7/avatar.svg"></a>
1420<a href="https://opencollective.com/terser/organization/8/website"><img src="https://opencollective.com/terser/organization/8/avatar.svg"></a>
1421<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.