terser 5.21.0 → 5.22.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 +6 -1
- package/README.md +3 -2
- package/dist/bundle.min.js +37 -8
- package/lib/compress/drop-unused.js +2 -0
- package/lib/compress/index.js +28 -7
- package/lib/scope.js +6 -0
- package/lib/size.js +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
@@ -1,6 +1,11 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
-
## v5.
|
3
|
+
## v5.22.0
|
4
|
+
- Do not `unsafe`ly shorten expressions like a?.toString() when they're conditional.
|
5
|
+
- Avoid running drop_unused in nodes that aren't scopes. Fixes a rare crash.
|
6
|
+
- When 'module' is enabled, assume strict mode when figuring out scopes.
|
7
|
+
|
8
|
+
## v5.21.0
|
4
9
|
- Do not inline functions that would be retained in the toplevel (as this would cause code duplication).
|
5
10
|
- Fix precedence of arrow function and ternary operator when formatting output.
|
6
11
|
|
package/README.md
CHANGED
@@ -154,7 +154,8 @@ a double dash to prevent input files being used as option arguments:
|
|
154
154
|
--keep-fnames Do not mangle/drop function names. Useful for
|
155
155
|
code relying on Function.prototype.name.
|
156
156
|
--module Input is an ES6 module. If `compress` or `mangle` is
|
157
|
-
enabled then the `toplevel` option
|
157
|
+
enabled then the `toplevel` option, as well as strict mode,
|
158
|
+
will be enabled.
|
158
159
|
--name-cache <file> File to hold mangled name mappings.
|
159
160
|
--safari10 Support non-standard Safari 10/11.
|
160
161
|
Equivalent to setting `safari10: true` in `minify()`
|
@@ -912,7 +913,7 @@ If you happen to need the source map as a raw object, set `sourceMap.asObject` t
|
|
912
913
|
[compress option](#compress-options).
|
913
914
|
|
914
915
|
- `module` (default `false`) -- Pass `true` an ES6 modules, where the toplevel
|
915
|
-
scope is not the global scope. Implies `toplevel
|
916
|
+
scope is not the global scope. Implies `toplevel` and assumes input code is strict mode JS.
|
916
917
|
|
917
918
|
- `nth_identifier` (default: an internal mangler that weights based on character
|
918
919
|
frequency analysis) -- Pass an object with a `get(n)` function that converts an
|
package/dist/bundle.min.js
CHANGED
@@ -11573,6 +11573,7 @@ AST_Scope.DEFMETHOD("figure_out_scope", function(options, { parent_scope = null,
|
|
11573
11573
|
cache: null,
|
11574
11574
|
ie8: false,
|
11575
11575
|
safari10: false,
|
11576
|
+
module: false,
|
11576
11577
|
});
|
11577
11578
|
|
11578
11579
|
if (!(toplevel instanceof AST_Toplevel)) {
|
@@ -11740,6 +11741,11 @@ AST_Scope.DEFMETHOD("figure_out_scope", function(options, { parent_scope = null,
|
|
11740
11741
|
);
|
11741
11742
|
}
|
11742
11743
|
});
|
11744
|
+
|
11745
|
+
if (options.module) {
|
11746
|
+
tw.directives["use strict"] = true;
|
11747
|
+
}
|
11748
|
+
|
11743
11749
|
this.walk(tw);
|
11744
11750
|
|
11745
11751
|
function mark_export(def, level) {
|
@@ -12424,7 +12430,7 @@ const base54 = (() => {
|
|
12424
12430
|
|
12425
12431
|
let mangle_options = undefined;
|
12426
12432
|
AST_Node.prototype.size = function (compressor, stack) {
|
12427
|
-
mangle_options = compressor && compressor.
|
12433
|
+
mangle_options = compressor && compressor._mangle_options;
|
12428
12434
|
|
12429
12435
|
let size = 0;
|
12430
12436
|
walk_parent(this, (node, info) => {
|
@@ -15077,6 +15083,8 @@ const r_keep_assign = /keep_assign/;
|
|
15077
15083
|
AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
|
15078
15084
|
if (!compressor.option("unused")) return;
|
15079
15085
|
if (compressor.has_directive("use asm")) return;
|
15086
|
+
if (!this.variables) return; // not really a scope (eg: AST_Class)
|
15087
|
+
|
15080
15088
|
var self = this;
|
15081
15089
|
if (self.pinned()) return;
|
15082
15090
|
var drop_funcs = !(self instanceof AST_Toplevel) || compressor.toplevel.funcs;
|
@@ -18406,11 +18414,17 @@ class Compressor extends TreeWalker {
|
|
18406
18414
|
this.sequences_limit = sequences == 1 ? 800 : sequences | 0;
|
18407
18415
|
this.evaluated_regexps = new Map();
|
18408
18416
|
this._toplevel = undefined;
|
18409
|
-
this.
|
18417
|
+
this._mangle_options = mangle_options
|
18410
18418
|
? format_mangler_options(mangle_options)
|
18411
18419
|
: mangle_options;
|
18412
18420
|
}
|
18413
18421
|
|
18422
|
+
mangle_options() {
|
18423
|
+
var nth_identifier = this._mangle_options && this._mangle_options.nth_identifier || base54;
|
18424
|
+
var module = this._mangle_options && this._mangle_options.module || this.option("module");
|
18425
|
+
return { ie8: this.option("ie8"), nth_identifier, module };
|
18426
|
+
}
|
18427
|
+
|
18414
18428
|
option(key) {
|
18415
18429
|
return this.options[key];
|
18416
18430
|
}
|
@@ -18465,8 +18479,7 @@ class Compressor extends TreeWalker {
|
|
18465
18479
|
var passes = +this.options.passes || 1;
|
18466
18480
|
var min_count = 1 / 0;
|
18467
18481
|
var stopping = false;
|
18468
|
-
var
|
18469
|
-
var mangle = { ie8: this.option("ie8"), nth_identifier: nth_identifier };
|
18482
|
+
var mangle = this.mangle_options();
|
18470
18483
|
for (var pass = 0; pass < passes; pass++) {
|
18471
18484
|
this._toplevel.figure_out_scope(mangle);
|
18472
18485
|
if (pass === 0 && this.option("drop_console")) {
|
@@ -19742,7 +19755,7 @@ def_optimize(AST_Call, function(self, compressor) {
|
|
19742
19755
|
self.args.length = last;
|
19743
19756
|
}
|
19744
19757
|
|
19745
|
-
if (compressor.option("unsafe")) {
|
19758
|
+
if (compressor.option("unsafe") && !exp.contains_optional()) {
|
19746
19759
|
if (exp instanceof AST_Dot && exp.start.value === "Array" && exp.property === "from" && self.args.length === 1) {
|
19747
19760
|
const [argument] = self.args;
|
19748
19761
|
if (argument instanceof AST_Array) {
|
@@ -19957,7 +19970,6 @@ def_optimize(AST_Call, function(self, compressor) {
|
|
19957
19970
|
argnames: [],
|
19958
19971
|
body: []
|
19959
19972
|
}).optimize(compressor);
|
19960
|
-
var nth_identifier = compressor.mangle_options && compressor.mangle_options.nth_identifier || base54;
|
19961
19973
|
if (self.args.every((x) => x instanceof AST_String)) {
|
19962
19974
|
// quite a corner-case, but we can handle it:
|
19963
19975
|
// https://github.com/mishoo/UglifyJS2/issues/203
|
@@ -19967,10 +19979,10 @@ def_optimize(AST_Call, function(self, compressor) {
|
|
19967
19979
|
return arg.value;
|
19968
19980
|
}).join(",") + "){" + self.args[self.args.length - 1].value + "})";
|
19969
19981
|
var ast = parse(code);
|
19970
|
-
var mangle =
|
19982
|
+
var mangle = compressor.mangle_options();
|
19971
19983
|
ast.figure_out_scope(mangle);
|
19972
19984
|
var comp = new Compressor(compressor.options, {
|
19973
|
-
mangle_options: compressor.
|
19985
|
+
mangle_options: compressor._mangle_options
|
19974
19986
|
});
|
19975
19987
|
ast = ast.transform(comp);
|
19976
19988
|
ast.figure_out_scope(mangle);
|
@@ -20009,6 +20021,23 @@ def_optimize(AST_Call, function(self, compressor) {
|
|
20009
20021
|
return inline_into_call(self, compressor);
|
20010
20022
|
});
|
20011
20023
|
|
20024
|
+
/** Does this node contain optional property access or optional call? */
|
20025
|
+
AST_Node.DEFMETHOD("contains_optional", function() {
|
20026
|
+
if (
|
20027
|
+
this instanceof AST_PropAccess
|
20028
|
+
|| this instanceof AST_Call
|
20029
|
+
|| this instanceof AST_Chain
|
20030
|
+
) {
|
20031
|
+
if (this.optional) {
|
20032
|
+
return true;
|
20033
|
+
} else {
|
20034
|
+
return this.expression.contains_optional();
|
20035
|
+
}
|
20036
|
+
} else {
|
20037
|
+
return false;
|
20038
|
+
}
|
20039
|
+
});
|
20040
|
+
|
20012
20041
|
def_optimize(AST_New, function(self, compressor) {
|
20013
20042
|
if (
|
20014
20043
|
compressor.option("unsafe") &&
|
@@ -109,6 +109,8 @@ const r_keep_assign = /keep_assign/;
|
|
109
109
|
AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
|
110
110
|
if (!compressor.option("unused")) return;
|
111
111
|
if (compressor.has_directive("use asm")) return;
|
112
|
+
if (!this.variables) return; // not really a scope (eg: AST_Class)
|
113
|
+
|
112
114
|
var self = this;
|
113
115
|
if (self.pinned()) return;
|
114
116
|
var drop_funcs = !(self instanceof AST_Toplevel) || compressor.toplevel.funcs;
|
package/lib/compress/index.js
CHANGED
@@ -320,11 +320,17 @@ class Compressor extends TreeWalker {
|
|
320
320
|
this.sequences_limit = sequences == 1 ? 800 : sequences | 0;
|
321
321
|
this.evaluated_regexps = new Map();
|
322
322
|
this._toplevel = undefined;
|
323
|
-
this.
|
323
|
+
this._mangle_options = mangle_options
|
324
324
|
? format_mangler_options(mangle_options)
|
325
325
|
: mangle_options;
|
326
326
|
}
|
327
327
|
|
328
|
+
mangle_options() {
|
329
|
+
var nth_identifier = this._mangle_options && this._mangle_options.nth_identifier || base54;
|
330
|
+
var module = this._mangle_options && this._mangle_options.module || this.option("module");
|
331
|
+
return { ie8: this.option("ie8"), nth_identifier, module };
|
332
|
+
}
|
333
|
+
|
328
334
|
option(key) {
|
329
335
|
return this.options[key];
|
330
336
|
}
|
@@ -379,8 +385,7 @@ class Compressor extends TreeWalker {
|
|
379
385
|
var passes = +this.options.passes || 1;
|
380
386
|
var min_count = 1 / 0;
|
381
387
|
var stopping = false;
|
382
|
-
var
|
383
|
-
var mangle = { ie8: this.option("ie8"), nth_identifier: nth_identifier };
|
388
|
+
var mangle = this.mangle_options();
|
384
389
|
for (var pass = 0; pass < passes; pass++) {
|
385
390
|
this._toplevel.figure_out_scope(mangle);
|
386
391
|
if (pass === 0 && this.option("drop_console")) {
|
@@ -1656,7 +1661,7 @@ def_optimize(AST_Call, function(self, compressor) {
|
|
1656
1661
|
self.args.length = last;
|
1657
1662
|
}
|
1658
1663
|
|
1659
|
-
if (compressor.option("unsafe")) {
|
1664
|
+
if (compressor.option("unsafe") && !exp.contains_optional()) {
|
1660
1665
|
if (exp instanceof AST_Dot && exp.start.value === "Array" && exp.property === "from" && self.args.length === 1) {
|
1661
1666
|
const [argument] = self.args;
|
1662
1667
|
if (argument instanceof AST_Array) {
|
@@ -1871,7 +1876,6 @@ def_optimize(AST_Call, function(self, compressor) {
|
|
1871
1876
|
argnames: [],
|
1872
1877
|
body: []
|
1873
1878
|
}).optimize(compressor);
|
1874
|
-
var nth_identifier = compressor.mangle_options && compressor.mangle_options.nth_identifier || base54;
|
1875
1879
|
if (self.args.every((x) => x instanceof AST_String)) {
|
1876
1880
|
// quite a corner-case, but we can handle it:
|
1877
1881
|
// https://github.com/mishoo/UglifyJS2/issues/203
|
@@ -1881,10 +1885,10 @@ def_optimize(AST_Call, function(self, compressor) {
|
|
1881
1885
|
return arg.value;
|
1882
1886
|
}).join(",") + "){" + self.args[self.args.length - 1].value + "})";
|
1883
1887
|
var ast = parse(code);
|
1884
|
-
var mangle =
|
1888
|
+
var mangle = compressor.mangle_options();
|
1885
1889
|
ast.figure_out_scope(mangle);
|
1886
1890
|
var comp = new Compressor(compressor.options, {
|
1887
|
-
mangle_options: compressor.
|
1891
|
+
mangle_options: compressor._mangle_options
|
1888
1892
|
});
|
1889
1893
|
ast = ast.transform(comp);
|
1890
1894
|
ast.figure_out_scope(mangle);
|
@@ -1923,6 +1927,23 @@ def_optimize(AST_Call, function(self, compressor) {
|
|
1923
1927
|
return inline_into_call(self, compressor);
|
1924
1928
|
});
|
1925
1929
|
|
1930
|
+
/** Does this node contain optional property access or optional call? */
|
1931
|
+
AST_Node.DEFMETHOD("contains_optional", function() {
|
1932
|
+
if (
|
1933
|
+
this instanceof AST_PropAccess
|
1934
|
+
|| this instanceof AST_Call
|
1935
|
+
|| this instanceof AST_Chain
|
1936
|
+
) {
|
1937
|
+
if (this.optional) {
|
1938
|
+
return true;
|
1939
|
+
} else {
|
1940
|
+
return this.expression.contains_optional();
|
1941
|
+
}
|
1942
|
+
} else {
|
1943
|
+
return false;
|
1944
|
+
}
|
1945
|
+
});
|
1946
|
+
|
1926
1947
|
def_optimize(AST_New, function(self, compressor) {
|
1927
1948
|
if (
|
1928
1949
|
compressor.option("unsafe") &&
|
package/lib/scope.js
CHANGED
@@ -205,6 +205,7 @@ AST_Scope.DEFMETHOD("figure_out_scope", function(options, { parent_scope = null,
|
|
205
205
|
cache: null,
|
206
206
|
ie8: false,
|
207
207
|
safari10: false,
|
208
|
+
module: false,
|
208
209
|
});
|
209
210
|
|
210
211
|
if (!(toplevel instanceof AST_Toplevel)) {
|
@@ -372,6 +373,11 @@ AST_Scope.DEFMETHOD("figure_out_scope", function(options, { parent_scope = null,
|
|
372
373
|
);
|
373
374
|
}
|
374
375
|
});
|
376
|
+
|
377
|
+
if (options.module) {
|
378
|
+
tw.directives["use strict"] = true;
|
379
|
+
}
|
380
|
+
|
375
381
|
this.walk(tw);
|
376
382
|
|
377
383
|
function mark_export(def, level) {
|
package/lib/size.js
CHANGED
@@ -89,7 +89,7 @@ import { first_in_statement } from "./utils/first_in_statement.js";
|
|
89
89
|
|
90
90
|
let mangle_options = undefined;
|
91
91
|
AST_Node.prototype.size = function (compressor, stack) {
|
92
|
-
mangle_options = compressor && compressor.
|
92
|
+
mangle_options = compressor && compressor._mangle_options;
|
93
93
|
|
94
94
|
let size = 0;
|
95
95
|
walk_parent(this, (node, info) => {
|