terser 5.16.8 → 5.16.9
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 +11 -1
- package/dist/bundle.min.js +26 -2
- package/lib/compress/common.js +3 -1
- package/lib/compress/index.js +18 -1
- package/lib/output.js +6 -0
- package/package.json +1 -1
- package/bin/terser.mjs +0 -21
package/CHANGELOG.md
CHANGED
@@ -1,11 +1,16 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## v5.16.9
|
4
|
+
- Fix parentheses in output of optional chains (`a?.b`) (#1374)
|
5
|
+
- More documentation on source maps (#1368)
|
6
|
+
- New `lhs_constants` option, allowing to stop Terser from swapping comparison operands (#1361)
|
7
|
+
|
3
8
|
## v5.16.8
|
4
9
|
|
5
10
|
- Become even less conservative around function definitions for `reduce_vars`
|
6
11
|
- Fix parsing context of `import.meta` expressions such that method calls are allowed
|
7
12
|
|
8
|
-
## v5.16.
|
13
|
+
## v5.16.6
|
9
14
|
|
10
15
|
- Become less conservative with analyzing function definitions for `reduce_vars`
|
11
16
|
- Parse `import.meta` as a real AST node and not an `object.property`
|
package/README.md
CHANGED
@@ -708,7 +708,8 @@ If you happen to need the source map as a raw object, set `sourceMap.asObject` t
|
|
708
708
|
|
709
709
|
- `comparisons` (default: `true`) -- apply certain optimizations to binary nodes,
|
710
710
|
e.g. `!(a <= b) → a > b` (only when `unsafe_comps`), attempts to negate binary
|
711
|
-
nodes, e.g. `a = !b && !c && !d && !e → a=!(b||c||d||e)` etc.
|
711
|
+
nodes, e.g. `a = !b && !c && !d && !e → a=!(b||c||d||e)` etc. Note: `comparisons`
|
712
|
+
works best with `lhs_constants` enabled.
|
712
713
|
|
713
714
|
- `computed_props` (default: `true`) -- Transforms constant computed properties
|
714
715
|
into regular ones: `{["computed"]: 1}` is converted to `{computed: 1}`.
|
@@ -775,6 +776,9 @@ If you happen to need the source map as a raw object, set `sourceMap.asObject` t
|
|
775
776
|
- `keep_infinity` (default: `false`) -- Pass `true` to prevent `Infinity` from
|
776
777
|
being compressed into `1/0`, which may cause performance issues on Chrome.
|
777
778
|
|
779
|
+
- `lhs_constants` (default: `true`) -- Moves constant values to the left-hand side
|
780
|
+
of binary nodes. `foo == 42 → 42 == foo`
|
781
|
+
|
778
782
|
- `loops` (default: `true`) -- optimizations for `do`, `while` and `for` loops
|
779
783
|
when we can statically determine the condition.
|
780
784
|
|
@@ -1267,6 +1271,12 @@ expected as code is optimized and mappings are often simply not possible as
|
|
1267
1271
|
some code no longer exists. For highest fidelity in source map debugging
|
1268
1272
|
disable the `compress` option and just use `mangle`.
|
1269
1273
|
|
1274
|
+
When debugging, make sure you enable the **"map scopes"** feature to map mangled variable names back to their original names.
|
1275
|
+
Without this, all variable values will be `undefined`. See https://github.com/terser/terser/issues/1367 for more details.
|
1276
|
+
<br/><br/>
|
1277
|
+
|
1278
|
+

|
1279
|
+
|
1270
1280
|
### Compiler assumptions
|
1271
1281
|
|
1272
1282
|
To allow for better optimizations, the compiler makes various assumptions:
|
package/dist/bundle.min.js
CHANGED
@@ -9742,6 +9742,12 @@ function OutputStream(options) {
|
|
9742
9742
|
return true;
|
9743
9743
|
});
|
9744
9744
|
|
9745
|
+
PARENS(AST_Chain, function(output) {
|
9746
|
+
var p = output.parent();
|
9747
|
+
if (!(p instanceof AST_Call || p instanceof AST_PropAccess)) return false;
|
9748
|
+
return p.expression === this;
|
9749
|
+
});
|
9750
|
+
|
9745
9751
|
PARENS(AST_PropAccess, function(output) {
|
9746
9752
|
var p = output.parent();
|
9747
9753
|
if (p instanceof AST_New && p.expression === this) {
|
@@ -12939,7 +12945,8 @@ function maintain_this_binding(parent, orig, val) {
|
|
12939
12945
|
parent instanceof AST_UnaryPrefix && parent.operator == "delete"
|
12940
12946
|
|| parent instanceof AST_Call && parent.expression === orig
|
12941
12947
|
&& (
|
12942
|
-
val instanceof
|
12948
|
+
val instanceof AST_Chain
|
12949
|
+
|| val instanceof AST_PropAccess
|
12943
12950
|
|| val instanceof AST_SymbolRef && val.name == "eval"
|
12944
12951
|
)
|
12945
12952
|
) {
|
@@ -18028,6 +18035,7 @@ class Compressor extends TreeWalker {
|
|
18028
18035
|
keep_fargs : true,
|
18029
18036
|
keep_fnames : false,
|
18030
18037
|
keep_infinity : false,
|
18038
|
+
lhs_constants : !false_by_default,
|
18031
18039
|
loops : !false_by_default,
|
18032
18040
|
module : false,
|
18033
18041
|
negate_iife : !false_by_default,
|
@@ -19914,7 +19922,7 @@ def_optimize(AST_Binary, function(self, compressor) {
|
|
19914
19922
|
self.right = tmp;
|
19915
19923
|
}
|
19916
19924
|
}
|
19917
|
-
if (commutativeOperators.has(self.operator)) {
|
19925
|
+
if (compressor.option("lhs_constants") && commutativeOperators.has(self.operator)) {
|
19918
19926
|
if (self.right.is_constant()
|
19919
19927
|
&& !self.left.is_constant()) {
|
19920
19928
|
// if right is a constant, whatever side effects the
|
@@ -19944,6 +19952,9 @@ def_optimize(AST_Binary, function(self, compressor) {
|
|
19944
19952
|
// void 0 == x => null == x
|
19945
19953
|
if (!is_strict_comparison && is_undefined(self.left, compressor)) {
|
19946
19954
|
self.left = make_node(AST_Null, self.left);
|
19955
|
+
// x == void 0 => x == null
|
19956
|
+
} else if (!is_strict_comparison && is_undefined(self.right, compressor)) {
|
19957
|
+
self.right = make_node(AST_Null, self.right);
|
19947
19958
|
} else if (compressor.option("typeofs")
|
19948
19959
|
// "undefined" == typeof x => undefined === x
|
19949
19960
|
&& self.left instanceof AST_String
|
@@ -19957,6 +19968,19 @@ def_optimize(AST_Binary, function(self, compressor) {
|
|
19957
19968
|
self.left = make_node(AST_Undefined, self.left).optimize(compressor);
|
19958
19969
|
if (self.operator.length == 2) self.operator += "=";
|
19959
19970
|
}
|
19971
|
+
} else if (compressor.option("typeofs")
|
19972
|
+
// typeof x === "undefined" => x === undefined
|
19973
|
+
&& self.left instanceof AST_UnaryPrefix
|
19974
|
+
&& self.left.operator == "typeof"
|
19975
|
+
&& self.right instanceof AST_String
|
19976
|
+
&& self.right.value == "undefined") {
|
19977
|
+
var expr = self.left.expression;
|
19978
|
+
if (expr instanceof AST_SymbolRef ? expr.is_declared(compressor)
|
19979
|
+
: !(expr instanceof AST_PropAccess && compressor.option("ie8"))) {
|
19980
|
+
self.left = expr;
|
19981
|
+
self.right = make_node(AST_Undefined, self.right).optimize(compressor);
|
19982
|
+
if (self.operator.length == 2) self.operator += "=";
|
19983
|
+
}
|
19960
19984
|
} else if (self.left instanceof AST_SymbolRef
|
19961
19985
|
// obj !== obj => false
|
19962
19986
|
&& self.right instanceof AST_SymbolRef
|
package/lib/compress/common.js
CHANGED
@@ -46,6 +46,7 @@ import {
|
|
46
46
|
AST_Arrow,
|
47
47
|
AST_BlockStatement,
|
48
48
|
AST_Call,
|
49
|
+
AST_Chain,
|
49
50
|
AST_Class,
|
50
51
|
AST_Const,
|
51
52
|
AST_Constant,
|
@@ -226,7 +227,8 @@ export function maintain_this_binding(parent, orig, val) {
|
|
226
227
|
parent instanceof AST_UnaryPrefix && parent.operator == "delete"
|
227
228
|
|| parent instanceof AST_Call && parent.expression === orig
|
228
229
|
&& (
|
229
|
-
val instanceof
|
230
|
+
val instanceof AST_Chain
|
231
|
+
|| val instanceof AST_PropAccess
|
230
232
|
|| val instanceof AST_SymbolRef && val.name == "eval"
|
231
233
|
)
|
232
234
|
) {
|
package/lib/compress/index.js
CHANGED
@@ -245,6 +245,7 @@ class Compressor extends TreeWalker {
|
|
245
245
|
keep_fargs : true,
|
246
246
|
keep_fnames : false,
|
247
247
|
keep_infinity : false,
|
248
|
+
lhs_constants : !false_by_default,
|
248
249
|
loops : !false_by_default,
|
249
250
|
module : false,
|
250
251
|
negate_iife : !false_by_default,
|
@@ -2131,7 +2132,7 @@ def_optimize(AST_Binary, function(self, compressor) {
|
|
2131
2132
|
self.right = tmp;
|
2132
2133
|
}
|
2133
2134
|
}
|
2134
|
-
if (commutativeOperators.has(self.operator)) {
|
2135
|
+
if (compressor.option("lhs_constants") && commutativeOperators.has(self.operator)) {
|
2135
2136
|
if (self.right.is_constant()
|
2136
2137
|
&& !self.left.is_constant()) {
|
2137
2138
|
// if right is a constant, whatever side effects the
|
@@ -2161,6 +2162,9 @@ def_optimize(AST_Binary, function(self, compressor) {
|
|
2161
2162
|
// void 0 == x => null == x
|
2162
2163
|
if (!is_strict_comparison && is_undefined(self.left, compressor)) {
|
2163
2164
|
self.left = make_node(AST_Null, self.left);
|
2165
|
+
// x == void 0 => x == null
|
2166
|
+
} else if (!is_strict_comparison && is_undefined(self.right, compressor)) {
|
2167
|
+
self.right = make_node(AST_Null, self.right);
|
2164
2168
|
} else if (compressor.option("typeofs")
|
2165
2169
|
// "undefined" == typeof x => undefined === x
|
2166
2170
|
&& self.left instanceof AST_String
|
@@ -2174,6 +2178,19 @@ def_optimize(AST_Binary, function(self, compressor) {
|
|
2174
2178
|
self.left = make_node(AST_Undefined, self.left).optimize(compressor);
|
2175
2179
|
if (self.operator.length == 2) self.operator += "=";
|
2176
2180
|
}
|
2181
|
+
} else if (compressor.option("typeofs")
|
2182
|
+
// typeof x === "undefined" => x === undefined
|
2183
|
+
&& self.left instanceof AST_UnaryPrefix
|
2184
|
+
&& self.left.operator == "typeof"
|
2185
|
+
&& self.right instanceof AST_String
|
2186
|
+
&& self.right.value == "undefined") {
|
2187
|
+
var expr = self.left.expression;
|
2188
|
+
if (expr instanceof AST_SymbolRef ? expr.is_declared(compressor)
|
2189
|
+
: !(expr instanceof AST_PropAccess && compressor.option("ie8"))) {
|
2190
|
+
self.left = expr;
|
2191
|
+
self.right = make_node(AST_Undefined, self.right).optimize(compressor);
|
2192
|
+
if (self.operator.length == 2) self.operator += "=";
|
2193
|
+
}
|
2177
2194
|
} else if (self.left instanceof AST_SymbolRef
|
2178
2195
|
// obj !== obj => false
|
2179
2196
|
&& self.right instanceof AST_SymbolRef
|
package/lib/output.js
CHANGED
@@ -1080,6 +1080,12 @@ function OutputStream(options) {
|
|
1080
1080
|
return true;
|
1081
1081
|
});
|
1082
1082
|
|
1083
|
+
PARENS(AST_Chain, function(output) {
|
1084
|
+
var p = output.parent();
|
1085
|
+
if (!(p instanceof AST_Call || p instanceof AST_PropAccess)) return false;
|
1086
|
+
return p.expression === this;
|
1087
|
+
});
|
1088
|
+
|
1083
1089
|
PARENS(AST_PropAccess, function(output) {
|
1084
1090
|
var p = output.parent();
|
1085
1091
|
if (p instanceof AST_New && p.expression === this) {
|
package/package.json
CHANGED
package/bin/terser.mjs
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
#!/usr/bin/env node
|
2
|
-
|
3
|
-
"use strict";
|
4
|
-
|
5
|
-
import "../tools/exit.cjs";
|
6
|
-
|
7
|
-
import fs from "fs";
|
8
|
-
import path from "path";
|
9
|
-
import program from "commander";
|
10
|
-
|
11
|
-
import { run_cli } from "../lib/cli.js";
|
12
|
-
|
13
|
-
const packageJson = {
|
14
|
-
name: "terser",
|
15
|
-
version: "experimental module CLI"
|
16
|
-
};
|
17
|
-
|
18
|
-
run_cli({ program, packageJson, fs, path }).catch((error) => {
|
19
|
-
console.error(error);
|
20
|
-
process.exitCode = 1;
|
21
|
-
});
|