terser 5.0.0 → 5.3.0
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.
- package/CHANGELOG.md +23 -0
- package/LICENSE +1 -1
- package/README.md +2 -6
- package/dist/bundle.min.js +2538 -97
- package/dist/bundle.min.js.map +1 -1
- package/lib/ast.js +28 -4
- package/lib/compress/index.js +179 -66
- package/lib/equivalent-to.js +3 -0
- package/lib/minify.js +5 -1
- package/lib/mozilla-ast.js +40 -3
- package/lib/output.js +18 -3
- package/lib/parse.js +107 -15
- package/lib/size.js +15 -4
- package/package.json +3 -2
- package/tools/domprops.js +2152 -1
- package/tools/terser.d.ts +2 -3
package/lib/output.js
CHANGED
@@ -65,6 +65,7 @@ import {
|
|
65
65
|
AST_Call,
|
66
66
|
AST_Case,
|
67
67
|
AST_Catch,
|
68
|
+
AST_Chain,
|
68
69
|
AST_Class,
|
69
70
|
AST_ClassExpression,
|
70
71
|
AST_ClassProperty,
|
@@ -94,6 +95,7 @@ import {
|
|
94
95
|
AST_Hole,
|
95
96
|
AST_If,
|
96
97
|
AST_Import,
|
98
|
+
AST_ImportMeta,
|
97
99
|
AST_Jump,
|
98
100
|
AST_LabeledStatement,
|
99
101
|
AST_Lambda,
|
@@ -894,8 +896,8 @@ function OutputStream(options) {
|
|
894
896
|
return p instanceof AST_PropAccess && p.expression === this;
|
895
897
|
});
|
896
898
|
|
897
|
-
// same goes for an object literal
|
898
|
-
// interpreted as a block of code.
|
899
|
+
// same goes for an object literal (as in AST_Function), because
|
900
|
+
// otherwise {...} would be interpreted as a block of code.
|
899
901
|
PARENS(AST_Object, function(output) {
|
900
902
|
return !output.has_parens() && first_in_statement(output);
|
901
903
|
});
|
@@ -1411,6 +1413,8 @@ function OutputStream(options) {
|
|
1411
1413
|
|| e instanceof AST_PropAccess
|
1412
1414
|
|| e instanceof AST_Unary
|
1413
1415
|
|| e instanceof AST_Constant
|
1416
|
+
|| e instanceof AST_Await
|
1417
|
+
|| e instanceof AST_Object
|
1414
1418
|
);
|
1415
1419
|
if (parens) output.print("(");
|
1416
1420
|
self.expression.print(output);
|
@@ -1608,6 +1612,9 @@ function OutputStream(options) {
|
|
1608
1612
|
self.module_name.print(output);
|
1609
1613
|
output.semicolon();
|
1610
1614
|
});
|
1615
|
+
DEFPRINT(AST_ImportMeta, function(self, output) {
|
1616
|
+
output.print("import.meta");
|
1617
|
+
});
|
1611
1618
|
|
1612
1619
|
DEFPRINT(AST_NameMapping, function(self, output) {
|
1613
1620
|
var is_import = output.parent() instanceof AST_Import;
|
@@ -1714,6 +1721,7 @@ function OutputStream(options) {
|
|
1714
1721
|
if (self.expression instanceof AST_Call || self.expression instanceof AST_Lambda) {
|
1715
1722
|
output.add_mapping(self.start);
|
1716
1723
|
}
|
1724
|
+
if (self.optional) output.print("?.");
|
1717
1725
|
output.with_parens(function() {
|
1718
1726
|
self.args.forEach(function(expr, i) {
|
1719
1727
|
if (i) output.comma();
|
@@ -1757,6 +1765,9 @@ function OutputStream(options) {
|
|
1757
1765
|
var print_computed = RESERVED_WORDS.has(prop)
|
1758
1766
|
? output.option("ie8")
|
1759
1767
|
: !is_identifier_string(prop, output.option("ecma") >= 2015);
|
1768
|
+
|
1769
|
+
if (self.optional) output.print("?.");
|
1770
|
+
|
1760
1771
|
if (print_computed) {
|
1761
1772
|
output.print("[");
|
1762
1773
|
output.add_mapping(self.end);
|
@@ -1768,7 +1779,7 @@ function OutputStream(options) {
|
|
1768
1779
|
output.print(".");
|
1769
1780
|
}
|
1770
1781
|
}
|
1771
|
-
output.print(".");
|
1782
|
+
if (!self.optional) output.print(".");
|
1772
1783
|
// the name after dot would be mapped about here.
|
1773
1784
|
output.add_mapping(self.end);
|
1774
1785
|
output.print_name(prop);
|
@@ -1776,10 +1787,14 @@ function OutputStream(options) {
|
|
1776
1787
|
});
|
1777
1788
|
DEFPRINT(AST_Sub, function(self, output) {
|
1778
1789
|
self.expression.print(output);
|
1790
|
+
if (self.optional) output.print("?.");
|
1779
1791
|
output.print("[");
|
1780
1792
|
self.property.print(output);
|
1781
1793
|
output.print("]");
|
1782
1794
|
});
|
1795
|
+
DEFPRINT(AST_Chain, function(self, output) {
|
1796
|
+
self.expression.print(output);
|
1797
|
+
});
|
1783
1798
|
DEFPRINT(AST_UnaryPrefix, function(self, output) {
|
1784
1799
|
var op = self.operator;
|
1785
1800
|
output.print(op);
|
package/lib/parse.js
CHANGED
@@ -63,6 +63,7 @@ import {
|
|
63
63
|
AST_Call,
|
64
64
|
AST_Case,
|
65
65
|
AST_Catch,
|
66
|
+
AST_Chain,
|
66
67
|
AST_ClassExpression,
|
67
68
|
AST_ClassProperty,
|
68
69
|
AST_ConciseMethod,
|
@@ -91,6 +92,7 @@ import {
|
|
91
92
|
AST_Hole,
|
92
93
|
AST_If,
|
93
94
|
AST_Import,
|
95
|
+
AST_ImportMeta,
|
94
96
|
AST_IterationStatement,
|
95
97
|
AST_Label,
|
96
98
|
AST_LabeledStatement,
|
@@ -396,6 +398,15 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|
396
398
|
|
397
399
|
function peek() { return get_full_char(S.text, S.pos); }
|
398
400
|
|
401
|
+
// Used because parsing ?. involves a lookahead for a digit
|
402
|
+
function is_option_chain_op() {
|
403
|
+
const must_be_dot = S.text.charCodeAt(S.pos + 1) === 46;
|
404
|
+
if (!must_be_dot) return false;
|
405
|
+
|
406
|
+
const cannot_be_digit = S.text.charCodeAt(S.pos + 2);
|
407
|
+
return cannot_be_digit < 48 || cannot_be_digit > 57;
|
408
|
+
}
|
409
|
+
|
399
410
|
function next(signal_eof, in_string) {
|
400
411
|
var ch = get_full_char(S.text, S.pos++);
|
401
412
|
if (signal_eof && !ch)
|
@@ -456,7 +467,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|
456
467
|
(type == "keyword" && KEYWORDS_BEFORE_EXPRESSION.has(value)) ||
|
457
468
|
(type == "punc" && PUNC_BEFORE_EXPRESSION.has(value))) ||
|
458
469
|
(type == "arrow");
|
459
|
-
if (type == "punc" && value == ".") {
|
470
|
+
if (type == "punc" && (value == "." || value == "?.")) {
|
460
471
|
prev_was_dot = true;
|
461
472
|
} else if (!is_comment) {
|
462
473
|
prev_was_dot = false;
|
@@ -892,6 +903,14 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|
892
903
|
return tok;
|
893
904
|
}
|
894
905
|
case 61: return handle_eq_sign();
|
906
|
+
case 63: {
|
907
|
+
if (!is_option_chain_op()) break; // Handled below
|
908
|
+
|
909
|
+
next(); // ?
|
910
|
+
next(); // .
|
911
|
+
|
912
|
+
return token("punc", "?.");
|
913
|
+
}
|
895
914
|
case 96: return read_template_characters(true);
|
896
915
|
case 123:
|
897
916
|
S.brace_counter++;
|
@@ -1010,7 +1029,7 @@ function parse($TEXT, options) {
|
|
1010
1029
|
|
1011
1030
|
options = defaults(options, {
|
1012
1031
|
bare_returns : false,
|
1013
|
-
ecma :
|
1032
|
+
ecma : null, // Legacy
|
1014
1033
|
expression : false,
|
1015
1034
|
filename : null,
|
1016
1035
|
html5_comments : true,
|
@@ -1118,7 +1137,7 @@ function parse($TEXT, options) {
|
|
1118
1137
|
}
|
1119
1138
|
|
1120
1139
|
function embed_tokens(parser) {
|
1121
|
-
return function(...args) {
|
1140
|
+
return function _embed_tokens_wrapper(...args) {
|
1122
1141
|
const start = S.token;
|
1123
1142
|
const expr = parser(...args);
|
1124
1143
|
expr.start = start;
|
@@ -1134,7 +1153,7 @@ function parse($TEXT, options) {
|
|
1134
1153
|
}
|
1135
1154
|
}
|
1136
1155
|
|
1137
|
-
var statement = embed_tokens(function(is_export_default, is_for_body, is_if_body) {
|
1156
|
+
var statement = embed_tokens(function statement(is_export_default, is_for_body, is_if_body) {
|
1138
1157
|
handle_regexp();
|
1139
1158
|
switch (S.token.type) {
|
1140
1159
|
case "string":
|
@@ -1169,7 +1188,7 @@ function parse($TEXT, options) {
|
|
1169
1188
|
}
|
1170
1189
|
return function_(AST_Defun, false, true, is_export_default);
|
1171
1190
|
}
|
1172
|
-
if (S.token.value == "import" && !is_token(peek(), "punc", "(")) {
|
1191
|
+
if (S.token.value == "import" && !is_token(peek(), "punc", "(") && !is_token(peek(), "punc", ".")) {
|
1173
1192
|
next();
|
1174
1193
|
var node = import_();
|
1175
1194
|
semicolon();
|
@@ -1590,7 +1609,6 @@ function parse($TEXT, options) {
|
|
1590
1609
|
|
1591
1610
|
if (!is("punc", ")")) {
|
1592
1611
|
expect(",");
|
1593
|
-
if (is("punc", ")") && options.ecma < 2017) unexpected();
|
1594
1612
|
}
|
1595
1613
|
|
1596
1614
|
if (param instanceof AST_Expansion) {
|
@@ -1835,7 +1853,6 @@ function parse($TEXT, options) {
|
|
1835
1853
|
if (!is("punc", ")")) {
|
1836
1854
|
expect(",");
|
1837
1855
|
if (is("punc", ")")) {
|
1838
|
-
if (options.ecma < 2017) unexpected();
|
1839
1856
|
trailing_comma = prev();
|
1840
1857
|
if (maybe_sequence) invalid_sequence = trailing_comma;
|
1841
1858
|
}
|
@@ -2104,7 +2121,7 @@ function parse($TEXT, options) {
|
|
2104
2121
|
var newexp = expr_atom(false), args;
|
2105
2122
|
if (is("punc", "(")) {
|
2106
2123
|
next();
|
2107
|
-
args = expr_list(")",
|
2124
|
+
args = expr_list(")", true);
|
2108
2125
|
} else {
|
2109
2126
|
args = [];
|
2110
2127
|
}
|
@@ -2217,6 +2234,9 @@ function parse($TEXT, options) {
|
|
2217
2234
|
if (is("operator", "new")) {
|
2218
2235
|
return new_(allow_calls);
|
2219
2236
|
}
|
2237
|
+
if (is("operator", "import")) {
|
2238
|
+
return import_meta();
|
2239
|
+
}
|
2220
2240
|
var start = S.token;
|
2221
2241
|
var peeked;
|
2222
2242
|
var async = is("name", "async")
|
@@ -2594,6 +2614,7 @@ function parse($TEXT, options) {
|
|
2594
2614
|
|
2595
2615
|
function import_() {
|
2596
2616
|
var start = prev();
|
2617
|
+
|
2597
2618
|
var imported_name;
|
2598
2619
|
var imported_names;
|
2599
2620
|
if (is("name")) {
|
@@ -2628,6 +2649,17 @@ function parse($TEXT, options) {
|
|
2628
2649
|
});
|
2629
2650
|
}
|
2630
2651
|
|
2652
|
+
function import_meta() {
|
2653
|
+
var start = S.token;
|
2654
|
+
expect_token("operator", "import");
|
2655
|
+
expect_token("punc", ".");
|
2656
|
+
expect_token("name", "meta");
|
2657
|
+
return subscripts(new AST_ImportMeta({
|
2658
|
+
start: start,
|
2659
|
+
end: prev()
|
2660
|
+
}), false);
|
2661
|
+
}
|
2662
|
+
|
2631
2663
|
function map_name(is_import) {
|
2632
2664
|
function make_symbol(type) {
|
2633
2665
|
return new type({
|
@@ -2889,16 +2921,17 @@ function parse($TEXT, options) {
|
|
2889
2921
|
}
|
2890
2922
|
}
|
2891
2923
|
|
2892
|
-
var subscripts = function(expr, allow_calls) {
|
2924
|
+
var subscripts = function(expr, allow_calls, is_chain) {
|
2893
2925
|
var start = expr.start;
|
2894
2926
|
if (is("punc", ".")) {
|
2895
2927
|
next();
|
2896
2928
|
return subscripts(new AST_Dot({
|
2897
2929
|
start : start,
|
2898
2930
|
expression : expr,
|
2931
|
+
optional : false,
|
2899
2932
|
property : as_name(),
|
2900
2933
|
end : prev()
|
2901
|
-
}), allow_calls);
|
2934
|
+
}), allow_calls, is_chain);
|
2902
2935
|
}
|
2903
2936
|
if (is("punc", "[")) {
|
2904
2937
|
next();
|
@@ -2907,22 +2940,80 @@ function parse($TEXT, options) {
|
|
2907
2940
|
return subscripts(new AST_Sub({
|
2908
2941
|
start : start,
|
2909
2942
|
expression : expr,
|
2943
|
+
optional : false,
|
2910
2944
|
property : prop,
|
2911
2945
|
end : prev()
|
2912
|
-
}), allow_calls);
|
2946
|
+
}), allow_calls, is_chain);
|
2913
2947
|
}
|
2914
2948
|
if (allow_calls && is("punc", "(")) {
|
2915
2949
|
next();
|
2916
2950
|
var call = new AST_Call({
|
2917
2951
|
start : start,
|
2918
2952
|
expression : expr,
|
2953
|
+
optional : false,
|
2919
2954
|
args : call_args(),
|
2920
2955
|
end : prev()
|
2921
2956
|
});
|
2922
2957
|
annotate(call);
|
2923
|
-
return subscripts(call, true);
|
2958
|
+
return subscripts(call, true, is_chain);
|
2924
2959
|
}
|
2960
|
+
|
2961
|
+
if (is("punc", "?.")) {
|
2962
|
+
next();
|
2963
|
+
|
2964
|
+
let chain_contents;
|
2965
|
+
|
2966
|
+
if (allow_calls && is("punc", "(")) {
|
2967
|
+
next();
|
2968
|
+
|
2969
|
+
const call = new AST_Call({
|
2970
|
+
start,
|
2971
|
+
optional: true,
|
2972
|
+
expression: expr,
|
2973
|
+
args: call_args(),
|
2974
|
+
end: prev()
|
2975
|
+
});
|
2976
|
+
annotate(call);
|
2977
|
+
|
2978
|
+
chain_contents = subscripts(call, true, true);
|
2979
|
+
} else if (is("name")) {
|
2980
|
+
chain_contents = subscripts(new AST_Dot({
|
2981
|
+
start,
|
2982
|
+
expression: expr,
|
2983
|
+
optional: true,
|
2984
|
+
property: as_name(),
|
2985
|
+
end: prev()
|
2986
|
+
}), allow_calls, true);
|
2987
|
+
} else if (is("punc", "[")) {
|
2988
|
+
next();
|
2989
|
+
const property = expression(true);
|
2990
|
+
expect("]");
|
2991
|
+
chain_contents = subscripts(new AST_Sub({
|
2992
|
+
start,
|
2993
|
+
expression: expr,
|
2994
|
+
optional: true,
|
2995
|
+
property,
|
2996
|
+
end: prev()
|
2997
|
+
}), allow_calls, true);
|
2998
|
+
}
|
2999
|
+
|
3000
|
+
if (!chain_contents) unexpected();
|
3001
|
+
|
3002
|
+
if (chain_contents instanceof AST_Chain) return chain_contents;
|
3003
|
+
|
3004
|
+
return new AST_Chain({
|
3005
|
+
start,
|
3006
|
+
expression: chain_contents,
|
3007
|
+
end: prev()
|
3008
|
+
});
|
3009
|
+
}
|
3010
|
+
|
2925
3011
|
if (is("template_head")) {
|
3012
|
+
if (is_chain) {
|
3013
|
+
// a?.b`c` is a syntax error
|
3014
|
+
unexpected();
|
3015
|
+
}
|
3016
|
+
|
2926
3017
|
return subscripts(new AST_PrefixedTemplateString({
|
2927
3018
|
start: start,
|
2928
3019
|
prefix: expr,
|
@@ -2930,6 +3021,7 @@ function parse($TEXT, options) {
|
|
2930
3021
|
end: prev()
|
2931
3022
|
}), allow_calls);
|
2932
3023
|
}
|
3024
|
+
|
2933
3025
|
return expr;
|
2934
3026
|
};
|
2935
3027
|
|
@@ -2948,7 +3040,6 @@ function parse($TEXT, options) {
|
|
2948
3040
|
}
|
2949
3041
|
if (!is("punc", ")")) {
|
2950
3042
|
expect(",");
|
2951
|
-
if (is("punc", ")") && options.ecma < 2017) unexpected();
|
2952
3043
|
}
|
2953
3044
|
}
|
2954
3045
|
next();
|
@@ -3152,13 +3243,14 @@ function parse($TEXT, options) {
|
|
3152
3243
|
return expression(true);
|
3153
3244
|
}
|
3154
3245
|
|
3155
|
-
return (function() {
|
3246
|
+
return (function parse_toplevel() {
|
3156
3247
|
var start = S.token;
|
3157
3248
|
var body = [];
|
3158
3249
|
S.input.push_directives_stack();
|
3159
3250
|
if (options.module) S.input.add_directive("use strict");
|
3160
|
-
while (!is("eof"))
|
3251
|
+
while (!is("eof")) {
|
3161
3252
|
body.push(statement());
|
3253
|
+
}
|
3162
3254
|
S.input.pop_directives_stack();
|
3163
3255
|
var end = prev();
|
3164
3256
|
var toplevel = options.toplevel;
|
package/lib/size.js
CHANGED
@@ -32,6 +32,7 @@ import {
|
|
32
32
|
AST_Hole,
|
33
33
|
AST_If,
|
34
34
|
AST_Import,
|
35
|
+
AST_ImportMeta,
|
35
36
|
AST_Infinity,
|
36
37
|
AST_LabeledStatement,
|
37
38
|
AST_Let,
|
@@ -81,7 +82,7 @@ import { first_in_statement } from "./utils/first_in_statement.js";
|
|
81
82
|
|
82
83
|
let mangle_options = undefined;
|
83
84
|
AST_Node.prototype.size = function (compressor, stack) {
|
84
|
-
mangle_options =
|
85
|
+
mangle_options = compressor && compressor.mangle_options;
|
85
86
|
|
86
87
|
let size = 0;
|
87
88
|
walk_parent(this, (node, info) => {
|
@@ -257,6 +258,8 @@ AST_Import.prototype._size = function () {
|
|
257
258
|
return size;
|
258
259
|
};
|
259
260
|
|
261
|
+
AST_ImportMeta.prototype._size = () => 11;
|
262
|
+
|
260
263
|
AST_Export.prototype._size = function () {
|
261
264
|
let size = 7 + (this.is_default ? 8 : 0);
|
262
265
|
|
@@ -278,6 +281,9 @@ AST_Export.prototype._size = function () {
|
|
278
281
|
};
|
279
282
|
|
280
283
|
AST_Call.prototype._size = function () {
|
284
|
+
if (this.optional) {
|
285
|
+
return 4 + list_overhead(this.args);
|
286
|
+
}
|
281
287
|
return 2 + list_overhead(this.args);
|
282
288
|
};
|
283
289
|
|
@@ -290,10 +296,15 @@ AST_Sequence.prototype._size = function () {
|
|
290
296
|
};
|
291
297
|
|
292
298
|
AST_Dot.prototype._size = function () {
|
299
|
+
if (this.optional) {
|
300
|
+
return this.property.length + 2;
|
301
|
+
}
|
293
302
|
return this.property.length + 1;
|
294
303
|
};
|
295
304
|
|
296
|
-
AST_Sub.prototype._size = ()
|
305
|
+
AST_Sub.prototype._size = function () {
|
306
|
+
return this.optional ? 4 : 2;
|
307
|
+
};
|
297
308
|
|
298
309
|
AST_Unary.prototype._size = function () {
|
299
310
|
if (this.operator === "typeof") return 7;
|
@@ -376,7 +387,7 @@ AST_ClassProperty.prototype._size = function () {
|
|
376
387
|
AST_Symbol.prototype._size = function () {
|
377
388
|
return !mangle_options || this.definition().unmangleable(mangle_options)
|
378
389
|
? this.name.length
|
379
|
-
:
|
390
|
+
: 1;
|
380
391
|
};
|
381
392
|
|
382
393
|
// TODO take propmangle into account
|
@@ -391,7 +402,7 @@ AST_SymbolRef.prototype._size = AST_SymbolDeclaration.prototype._size = function
|
|
391
402
|
|
392
403
|
if (name === "arguments") return 9;
|
393
404
|
|
394
|
-
return
|
405
|
+
return AST_Symbol.prototype._size.call(this);
|
395
406
|
};
|
396
407
|
|
397
408
|
AST_NewTarget.prototype._size = () => 10;
|
package/package.json
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
"homepage": "https://terser.org",
|
5
5
|
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
6
6
|
"license": "BSD-2-Clause",
|
7
|
-
"version": "5.
|
7
|
+
"version": "5.3.0",
|
8
8
|
"engines": {
|
9
9
|
"node": ">=6.0.0"
|
10
10
|
},
|
@@ -14,6 +14,7 @@
|
|
14
14
|
"repository": "https://github.com/terser/terser",
|
15
15
|
"main": "dist/bundle.min.js",
|
16
16
|
"type": "module",
|
17
|
+
"module": "./main.js",
|
17
18
|
"exports": {
|
18
19
|
".": {
|
19
20
|
"import": "./main.js",
|
@@ -48,7 +49,7 @@
|
|
48
49
|
},
|
49
50
|
"devDependencies": {
|
50
51
|
"@ls-lint/ls-lint": "^1.9.2",
|
51
|
-
"acorn": "^7.
|
52
|
+
"acorn": "^7.4.0",
|
52
53
|
"astring": "^1.4.1",
|
53
54
|
"eslint": "^7.0.0",
|
54
55
|
"eslump": "^2.0.0",
|