terser 3.9.2 → 3.10.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of terser might be problematic. Click here for more details.
- package/README.md +17 -11
- package/bin/uglifyjs +46 -22
- package/dist/{browser.bundle.js → bundle.js} +35 -23
- package/dist/bundle.js.map +1 -0
- package/lib/ast.js +1 -1
- package/lib/compress.js +20 -8
- package/lib/output.js +6 -4
- package/lib/parse.js +14 -7
- package/lib/scope.js +2 -2
- package/lib/transform.js +1 -1
- package/package.json +10 -6
- package/tools/exports.js +1 -0
- package/tools/node.js +6 -37
- package/dist/browser.bundle.js.map +0 -1
package/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
terser
|
2
2
|
======
|
3
3
|
|
4
|
-
[](https://travis-ci.org/terser-js/terser)
|
4
|
+
[](https://travis-ci.org/terser-js/terser) [](https://coveralls.io/github/terser-js/terser?branch=master)
|
5
5
|
|
6
6
|
A JavaScript parser, mangler/compressor and beautifier toolkit for ES6+.
|
7
7
|
|
@@ -127,7 +127,6 @@ a double dash to prevent input files being used as option arguments:
|
|
127
127
|
for `mangle` and `output` options.
|
128
128
|
By default `terser` will not work around
|
129
129
|
Safari 10/11 bugs.
|
130
|
-
--self Build Terser as a library (implies --wrap Terser)
|
131
130
|
--source-map [options] Enable source map/specify source map options:
|
132
131
|
`base` Path to compute relative paths from input files.
|
133
132
|
`content` Input source map, useful if you're compressing
|
@@ -531,12 +530,13 @@ if (result.error) throw result.error;
|
|
531
530
|
- `ie8` (default `false`) - set to `true` to support IE8.
|
532
531
|
|
533
532
|
- `keep_classnames` (default: `undefined`) - pass `true` to prevent discarding or mangling
|
534
|
-
of class names.
|
533
|
+
of class names. Pass a regular expression to only keep class names matching that regex.
|
535
534
|
|
536
535
|
- `keep_fnames` (default: `false`) - pass `true` to prevent discarding or mangling
|
537
|
-
of function names.
|
538
|
-
|
539
|
-
the value of the top level
|
536
|
+
of function names. Pass a regular expression to only keep class names matching that regex.
|
537
|
+
Useful for code relying on `Function.prototype.name`. If the top level minify option
|
538
|
+
`keep_classnames` is `undefined` it will be overridden with the value of the top level
|
539
|
+
minify option `keep_fnames`.
|
540
540
|
|
541
541
|
- `safari10` (default: `false`) - pass `true` to work around Safari 10/11 bugs in
|
542
542
|
loop scoping and `await`. See `safari10` options in [`mangle`](#mangle-options)
|
@@ -648,6 +648,9 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u
|
|
648
648
|
- `booleans` (default: `true`) -- various optimizations for boolean context,
|
649
649
|
for example `!!a ? b : c → a ? b : c`
|
650
650
|
|
651
|
+
- `booleans_as_integers` (default: `false`) -- Turn booleans into 0 and 1, also
|
652
|
+
makes comparisons with booleans use `==` and `!=` instead of `===` and `!==`.
|
653
|
+
|
651
654
|
- `collapse_vars` (default: `true`) -- Collapse single-use non-constant variables,
|
652
655
|
side effects permitting.
|
653
656
|
|
@@ -709,16 +712,17 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u
|
|
709
712
|
|
710
713
|
- `join_vars` (default: `true`) -- join consecutive `var` statements
|
711
714
|
|
712
|
-
- `keep_classnames` (default: `false`) -- Pass `true` to prevent the
|
713
|
-
|
714
|
-
[mangle option](#mangle).
|
715
|
+
- `keep_classnames` (default: `false`) -- Pass `true` to prevent the compressor from
|
716
|
+
discarding class names. Pass a regular expression to only keep class names matching
|
717
|
+
that regex. See also: the `keep_classnames` [mangle option](#mangle).
|
715
718
|
|
716
719
|
- `keep_fargs` (default: `true`) -- Prevents the compressor from discarding unused
|
717
720
|
function arguments. You need this for code which relies on `Function.length`.
|
718
721
|
|
719
722
|
- `keep_fnames` (default: `false`) -- Pass `true` to prevent the
|
720
|
-
compressor from discarding function names.
|
721
|
-
|
723
|
+
compressor from discarding function names. Pass a regular expression to only keep
|
724
|
+
class names matching that regex. Useful for code relying on `Function.prototype.name`.
|
725
|
+
See also: the `keep_fnames` [mangle option](#mangle).
|
722
726
|
|
723
727
|
- `keep_infinity` (default: `false`) -- Pass `true` to prevent `Infinity` from
|
724
728
|
being compressed into `1/0`, which may cause performance issues on Chrome.
|
@@ -845,9 +849,11 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u
|
|
845
849
|
where `eval` or `with` are used.
|
846
850
|
|
847
851
|
- `keep_classnames` (default `false`) -- Pass `true` to not mangle class names.
|
852
|
+
Pass a regular expression to only keep class names matching that regex.
|
848
853
|
See also: the `keep_classnames` [compress option](#compress-options).
|
849
854
|
|
850
855
|
- `keep_fnames` (default `false`) -- Pass `true` to not mangle function names.
|
856
|
+
Pass a regular expression to only keep class names matching that regex.
|
851
857
|
Useful for code relying on `Function.prototype.name`. See also: the `keep_fnames`
|
852
858
|
[compress option](#compress-options).
|
853
859
|
|
package/bin/uglifyjs
CHANGED
@@ -10,15 +10,14 @@ var info = require("../package.json");
|
|
10
10
|
var path = require("path");
|
11
11
|
var program = require("commander");
|
12
12
|
|
13
|
-
var bundle_path = __dirname + "/../dist/
|
14
|
-
if (
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
} catch (err) {}
|
13
|
+
var bundle_path = __dirname + "/../dist/bundle.js";
|
14
|
+
if (fs.existsSync(bundle_path)) {
|
15
|
+
var UglifyJS = require(bundle_path)
|
16
|
+
if (process.env.TERSER_DEBUG) {
|
17
|
+
try {
|
18
|
+
require("source-map-support").install();
|
19
|
+
} catch (err) {}
|
20
|
+
}
|
22
21
|
} else {
|
23
22
|
var UglifyJS = require("../tools/node.js");
|
24
23
|
}
|
@@ -32,7 +31,7 @@ var options = {
|
|
32
31
|
program.version(info.name + " " + info.version);
|
33
32
|
program.parseArgv = program.parse;
|
34
33
|
program.parse = undefined;
|
35
|
-
if (process.argv.indexOf("ast") >= 0) program.helpInformation =
|
34
|
+
if (process.argv.indexOf("ast") >= 0) program.helpInformation = describe_ast;
|
36
35
|
else if (process.argv.indexOf("options") >= 0) program.helpInformation = function() {
|
37
36
|
var text = [];
|
38
37
|
var options = UglifyJS.default_options();
|
@@ -62,7 +61,6 @@ program.option("--name-cache <file>", "File to hold mangled name mappings.");
|
|
62
61
|
program.option("--rename", "Force symbol expansion.");
|
63
62
|
program.option("--no-rename", "Disable symbol expansion.");
|
64
63
|
program.option("--safari10", "Support non-standard Safari 10.");
|
65
|
-
program.option("--self", "Build Terser as a library (implies --wrap Terser)");
|
66
64
|
program.option("--source-map [options]", "Enable source map/specify source map options.", parse_source_map());
|
67
65
|
program.option("--timings", "Display operations run time on STDERR.");
|
68
66
|
program.option("--toplevel", "Compress and/or mangle variables in toplevel scope.");
|
@@ -169,16 +167,7 @@ if (program.verbose) {
|
|
169
167
|
} else if (program.warn) {
|
170
168
|
options.warnings = true;
|
171
169
|
}
|
172
|
-
if (program.
|
173
|
-
if (program.args.length) {
|
174
|
-
print_error("WARN: Ignoring input files since --self was passed");
|
175
|
-
}
|
176
|
-
if (!options.wrap) options.wrap = "Terser";
|
177
|
-
simple_glob(UglifyJS.FILES).forEach(function(name) {
|
178
|
-
files[convert_path(name)] = read_file(name);
|
179
|
-
});
|
180
|
-
run();
|
181
|
-
} else if (program.args.length) {
|
170
|
+
if (program.args.length) {
|
182
171
|
simple_glob(program.args).forEach(function(name) {
|
183
172
|
files[convert_path(name)] = read_file(name);
|
184
173
|
});
|
@@ -328,7 +317,7 @@ function simple_glob(glob) {
|
|
328
317
|
if (Array.isArray(glob)) {
|
329
318
|
return [].concat.apply([], glob.map(simple_glob));
|
330
319
|
}
|
331
|
-
if (glob.match(/\*|\?/)) {
|
320
|
+
if (glob && glob.match(/\*|\?/)) {
|
332
321
|
var dir = path.dirname(glob);
|
333
322
|
try {
|
334
323
|
var entries = fs.readdirSync(dir);
|
@@ -455,3 +444,38 @@ function print(txt) {
|
|
455
444
|
process.stdout.write(txt);
|
456
445
|
process.stdout.write("\n");
|
457
446
|
}
|
447
|
+
|
448
|
+
function describe_ast() {
|
449
|
+
var out = UglifyJS.OutputStream({ beautify: true });
|
450
|
+
function doitem(ctor) {
|
451
|
+
out.print("AST_" + ctor.TYPE);
|
452
|
+
var props = ctor.SELF_PROPS.filter(function(prop){
|
453
|
+
return !/^\$/.test(prop);
|
454
|
+
});
|
455
|
+
if (props.length > 0) {
|
456
|
+
out.space();
|
457
|
+
out.with_parens(function(){
|
458
|
+
props.forEach(function(prop, i){
|
459
|
+
if (i) out.space();
|
460
|
+
out.print(prop);
|
461
|
+
});
|
462
|
+
});
|
463
|
+
}
|
464
|
+
if (ctor.documentation) {
|
465
|
+
out.space();
|
466
|
+
out.print_string(ctor.documentation);
|
467
|
+
}
|
468
|
+
if (ctor.SUBCLASSES.length > 0) {
|
469
|
+
out.space();
|
470
|
+
out.with_block(function(){
|
471
|
+
ctor.SUBCLASSES.forEach(function(ctor, i){
|
472
|
+
out.indent();
|
473
|
+
doitem(ctor);
|
474
|
+
out.newline();
|
475
|
+
});
|
476
|
+
});
|
477
|
+
}
|
478
|
+
};
|
479
|
+
doitem(UglifyJS.AST_Node);
|
480
|
+
return out + "\n";
|
481
|
+
}
|
@@ -763,7 +763,7 @@
|
|
763
763
|
},
|
764
764
|
_walk: function(visitor) {
|
765
765
|
return visitor._visit(this, function() {
|
766
|
-
this.argname._walk(visitor);
|
766
|
+
if (this.argname) this.argname._walk(visitor);
|
767
767
|
walk_body(this, visitor);
|
768
768
|
});
|
769
769
|
}
|
@@ -1516,7 +1516,7 @@
|
|
1516
1516
|
var valid = parse_js_number(num);
|
1517
1517
|
if (!isNaN(valid)) return token("num", valid); else parse_error("Invalid syntax: " + num);
|
1518
1518
|
}
|
1519
|
-
function read_escaped_char(in_string) {
|
1519
|
+
function read_escaped_char(in_string, template_string) {
|
1520
1520
|
var ch = next(true, in_string);
|
1521
1521
|
switch (ch.charCodeAt(0)) {
|
1522
1522
|
case 110:
|
@@ -1550,7 +1550,7 @@
|
|
1550
1550
|
next(true);
|
1551
1551
|
return from_char_code(result);
|
1552
1552
|
}
|
1553
|
-
return String.fromCharCode(hex_bytes(4));
|
1553
|
+
return String.fromCharCode(hex_bytes(4, template_string));
|
1554
1554
|
|
1555
1555
|
case 10:
|
1556
1556
|
return "";
|
@@ -1574,9 +1574,10 @@
|
|
1574
1574
|
if (ch.length > 0 && next_token.has_directive("use strict")) parse_error("Legacy octal escape sequences are not allowed in strict mode");
|
1575
1575
|
return String.fromCharCode(parseInt(ch, 8));
|
1576
1576
|
}
|
1577
|
-
function hex_bytes(n) {
|
1577
|
+
function hex_bytes(n, abrupt_ending) {
|
1578
1578
|
var num = 0;
|
1579
1579
|
for (;n > 0; --n) {
|
1580
|
+
if (abrupt_ending && isNaN(parseInt(peek(), 16))) return num || "";
|
1580
1581
|
var digit = parseInt(next(true), 16);
|
1581
1582
|
if (isNaN(digit)) parse_error("Invalid hex-character pattern in string");
|
1582
1583
|
num = num << 4 | digit;
|
@@ -1614,7 +1615,7 @@
|
|
1614
1615
|
raw += ch;
|
1615
1616
|
if ("\\" == ch) {
|
1616
1617
|
var tmp = S.pos;
|
1617
|
-
ch = read_escaped_char(true);
|
1618
|
+
ch = read_escaped_char(true, true);
|
1618
1619
|
raw += S.text.substr(tmp, S.pos - tmp);
|
1619
1620
|
}
|
1620
1621
|
content += ch;
|
@@ -2640,9 +2641,11 @@
|
|
2640
2641
|
if (is("keyword", "catch")) {
|
2641
2642
|
var start = S.token;
|
2642
2643
|
next();
|
2643
|
-
|
2644
|
-
|
2645
|
-
|
2644
|
+
if (is("punc", "{")) var name = null; else {
|
2645
|
+
expect("(");
|
2646
|
+
var name = parameter(void 0, AST_SymbolCatch);
|
2647
|
+
expect(")");
|
2648
|
+
}
|
2646
2649
|
bcatch = new AST_Catch({
|
2647
2650
|
start: start,
|
2648
2651
|
argname: name,
|
@@ -3662,7 +3665,7 @@
|
|
3662
3665
|
if (self.bfinally) self.bfinally = self.bfinally.transform(tw);
|
3663
3666
|
});
|
3664
3667
|
_(AST_Catch, function(self, tw) {
|
3665
|
-
self.argname = self.argname.transform(tw);
|
3668
|
+
if (self.argname) self.argname = self.argname.transform(tw);
|
3666
3669
|
self.body = do_list(self.body, tw);
|
3667
3670
|
});
|
3668
3671
|
_(AST_Definitions, function(self, tw) {
|
@@ -3770,7 +3773,7 @@
|
|
3770
3773
|
SymbolDef.prototype = {
|
3771
3774
|
unmangleable: function(options) {
|
3772
3775
|
if (!options) options = {};
|
3773
|
-
return this.global && !options.toplevel || this.export || this.undeclared || !options.eval && this.scope.pinned() || options.keep_fnames && (this.orig[0] instanceof AST_SymbolLambda || this.orig[0] instanceof AST_SymbolDefun) || this.orig[0] instanceof AST_SymbolMethod || options.keep_classnames && (this.orig[0] instanceof AST_SymbolClass || this.orig[0] instanceof AST_SymbolDefClass);
|
3776
|
+
return this.global && !options.toplevel || this.export || this.undeclared || !options.eval && this.scope.pinned() || (options.keep_fnames instanceof RegExp && options.keep_fnames.test(this.orig[0].name) || true === options.keep_fnames) && (this.orig[0] instanceof AST_SymbolLambda || this.orig[0] instanceof AST_SymbolDefun) || this.orig[0] instanceof AST_SymbolMethod || (options.keep_classnames instanceof RegExp && options.keep_classnames.test(this.orig[0].name) || true === options.keep_classnames) && (this.orig[0] instanceof AST_SymbolClass || this.orig[0] instanceof AST_SymbolDefClass);
|
3774
3777
|
},
|
3775
3778
|
mangle: function(options) {
|
3776
3779
|
var cache = options.cache && options.cache.props;
|
@@ -5208,10 +5211,12 @@
|
|
5208
5211
|
});
|
5209
5212
|
DEFPRINT(AST_Catch, function(self, output) {
|
5210
5213
|
output.print("catch");
|
5211
|
-
|
5212
|
-
|
5213
|
-
|
5214
|
-
|
5214
|
+
if (self.argname) {
|
5215
|
+
output.space();
|
5216
|
+
output.with_parens(function() {
|
5217
|
+
self.argname.print(output);
|
5218
|
+
});
|
5219
|
+
}
|
5215
5220
|
output.space();
|
5216
5221
|
print_braced(self, output);
|
5217
5222
|
});
|
@@ -5595,6 +5600,7 @@
|
|
5595
5600
|
arguments: false,
|
5596
5601
|
arrows: !false_by_default,
|
5597
5602
|
booleans: !false_by_default,
|
5603
|
+
booleans_as_integers: false,
|
5598
5604
|
collapse_vars: !false_by_default,
|
5599
5605
|
comparisons: !false_by_default,
|
5600
5606
|
computed_props: !false_by_default,
|
@@ -6272,7 +6278,7 @@
|
|
6272
6278
|
var scope, i = 0;
|
6273
6279
|
while (scope = compressor.parent(i++)) {
|
6274
6280
|
if (scope instanceof AST_Scope) break;
|
6275
|
-
if (scope instanceof AST_Catch) {
|
6281
|
+
if (scope instanceof AST_Catch && scope.argname) {
|
6276
6282
|
scope = scope.argname.definition().scope;
|
6277
6283
|
break;
|
6278
6284
|
}
|
@@ -9236,10 +9242,6 @@
|
|
9236
9242
|
});
|
9237
9243
|
}
|
9238
9244
|
break;
|
9239
|
-
|
9240
|
-
case "Symbol":
|
9241
|
-
self.args = [];
|
9242
|
-
return self;
|
9243
9245
|
} else if (exp instanceof AST_Dot) switch (exp.property) {
|
9244
9246
|
case "toString":
|
9245
9247
|
if (0 == self.args.length && !exp.expression.may_throw_on_access(compressor)) return make_node(AST_Binary, self, {
|
@@ -9407,7 +9409,8 @@
|
|
9407
9409
|
if (can_inline && stat instanceof AST_Return && is_regular_func) {
|
9408
9410
|
var value = stat.value;
|
9409
9411
|
if (!value || value.is_constant_expression()) {
|
9410
|
-
|
9412
|
+
if (value) value = value.clone(true); else value = make_node(AST_Undefined, self);
|
9413
|
+
var args = self.args.concat(value);
|
9411
9414
|
return make_sequence(self, args).optimize(compressor);
|
9412
9415
|
}
|
9413
9416
|
}
|
@@ -9499,7 +9502,9 @@
|
|
9499
9502
|
if (scope.is_block_scope() && !(compressor.parent(level - 1) instanceof AST_Scope)) if (scope.block_scope) scope.block_scope.variables.each(function(variable) {
|
9500
9503
|
block_scoped[variable.name] = true;
|
9501
9504
|
});
|
9502
|
-
if (scope instanceof AST_Catch)
|
9505
|
+
if (scope instanceof AST_Catch) {
|
9506
|
+
if (scope.argname) block_scoped[scope.argname.name] = true;
|
9507
|
+
} else if (scope instanceof AST_IterationStatement) in_loop = []; else if (scope instanceof AST_SymbolRef) if (scope.fixed_value() instanceof AST_Scope) return false;
|
9503
9508
|
} while (!(scope instanceof AST_Scope) || scope instanceof AST_Arrow);
|
9504
9509
|
var safe_to_inject = !(scope instanceof AST_Toplevel) || compressor.toplevel.vars;
|
9505
9510
|
var inline = compressor.option("inline");
|
@@ -10369,8 +10374,14 @@
|
|
10369
10374
|
if (compressor.in_boolean_context()) return make_node(AST_Number, self, {
|
10370
10375
|
value: +self.value
|
10371
10376
|
});
|
10377
|
+
var p = compressor.parent();
|
10378
|
+
if (compressor.option("booleans_as_integers")) {
|
10379
|
+
if (p instanceof AST_Binary && ("===" == p.operator || "!==" == p.operator)) p.operator = p.operator.replace(/=$/, "");
|
10380
|
+
return make_node(AST_Number, self, {
|
10381
|
+
value: +self.value
|
10382
|
+
});
|
10383
|
+
}
|
10372
10384
|
if (compressor.option("booleans")) {
|
10373
|
-
var p = compressor.parent();
|
10374
10385
|
if (p instanceof AST_Binary && ("==" == p.operator || "!=" == p.operator)) {
|
10375
10386
|
compressor.warn("Non-strict equality against boolean: {operator} {value} [{file}:{line},{col}]", {
|
10376
10387
|
operator: p.operator,
|
@@ -11990,7 +12001,8 @@
|
|
11990
12001
|
exports["minify"] = minify;
|
11991
12002
|
exports["parse"] = parse;
|
11992
12003
|
exports["push_uniq"] = push_uniq;
|
12004
|
+
exports["OutputStream"] = OutputStream;
|
11993
12005
|
exports["TreeTransformer"] = TreeTransformer;
|
11994
12006
|
exports["TreeWalker"] = TreeWalker;
|
11995
12007
|
})("undefined" != typeof module ? module.exports : Terser = {});
|
11996
|
-
//# sourceMappingURL=
|
12008
|
+
//# sourceMappingURL=bundle.js.map
|