terser 5.31.0 → 5.31.1
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 +3 -0
- package/dist/bundle.min.js +64 -8
- package/lib/compress/common.js +12 -7
- package/lib/compress/drop-unused.js +53 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## v5.31.1
|
4
|
+
- Allow drop-unused to drop the whole assignment (not just the assigned name) in more situations, in order to avoid duplication of long strings.
|
5
|
+
|
3
6
|
## v5.31.0
|
4
7
|
- Sync up property mangler exceptions with current contents of Firefox and Chrome environments
|
5
8
|
- Add more webcomponent properties to property mangler exceptions (#1525)
|
package/dist/bundle.min.js
CHANGED
@@ -13159,7 +13159,17 @@ function has_break_or_continue(loop, parent) {
|
|
13159
13159
|
// func(something) because that changes the meaning of
|
13160
13160
|
// the func (becomes lexical instead of global).
|
13161
13161
|
function maintain_this_binding(parent, orig, val) {
|
13162
|
-
if (
|
13162
|
+
if (requires_sequence_to_maintain_binding(parent, orig, val)) {
|
13163
|
+
const zero = make_node(AST_Number, orig, { value: 0 });
|
13164
|
+
return make_sequence(orig, [ zero, val ]);
|
13165
|
+
} else {
|
13166
|
+
return val;
|
13167
|
+
}
|
13168
|
+
}
|
13169
|
+
|
13170
|
+
/** Detect (1, x.noThis)(), (0, eval)(), which need sequences */
|
13171
|
+
function requires_sequence_to_maintain_binding(parent, orig, val) {
|
13172
|
+
return (
|
13163
13173
|
parent instanceof AST_UnaryPrefix && parent.operator == "delete"
|
13164
13174
|
|| parent instanceof AST_Call && parent.expression === orig
|
13165
13175
|
&& (
|
@@ -13167,12 +13177,7 @@ function maintain_this_binding(parent, orig, val) {
|
|
13167
13177
|
|| val instanceof AST_PropAccess
|
13168
13178
|
|| val instanceof AST_SymbolRef && val.name == "eval"
|
13169
13179
|
)
|
13170
|
-
)
|
13171
|
-
const zero = make_node(AST_Number, orig, { value: 0 });
|
13172
|
-
return make_sequence(orig, [ zero, val ]);
|
13173
|
-
} else {
|
13174
|
-
return val;
|
13175
|
-
}
|
13180
|
+
);
|
13176
13181
|
}
|
13177
13182
|
|
13178
13183
|
function is_func_expr(node) {
|
@@ -15361,7 +15366,11 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
|
|
15361
15366
|
var in_use = in_use_ids.has(def.id);
|
15362
15367
|
if (node instanceof AST_Assign) {
|
15363
15368
|
if (!in_use || fixed_ids.has(def.id) && fixed_ids.get(def.id) !== node) {
|
15364
|
-
|
15369
|
+
const assignee = node.right.transform(tt);
|
15370
|
+
if (!in_use && !assignee.has_side_effects(compressor) && !is_used_in_expression(tt)) {
|
15371
|
+
return in_list ? MAP.skip : make_node(AST_Number, node, { value: 0 });
|
15372
|
+
}
|
15373
|
+
return maintain_this_binding(parent, node, assignee);
|
15365
15374
|
}
|
15366
15375
|
} else if (!in_use) {
|
15367
15376
|
return in_list ? MAP.skip : make_node(AST_Number, node, { value: 0 });
|
@@ -15568,6 +15577,14 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
|
|
15568
15577
|
scope = save_scope;
|
15569
15578
|
return node;
|
15570
15579
|
}
|
15580
|
+
},
|
15581
|
+
function after(node, in_list) {
|
15582
|
+
if (node instanceof AST_Sequence) {
|
15583
|
+
switch (node.expressions.length) {
|
15584
|
+
case 0: return in_list ? MAP.skip : make_node(AST_Number, node, { value: 0 });
|
15585
|
+
case 1: return node.expressions[0];
|
15586
|
+
}
|
15587
|
+
}
|
15571
15588
|
}
|
15572
15589
|
);
|
15573
15590
|
|
@@ -15614,6 +15631,45 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
|
|
15614
15631
|
}
|
15615
15632
|
});
|
15616
15633
|
|
15634
|
+
/**
|
15635
|
+
* Check if a node may be used by the expression it's in
|
15636
|
+
* void (0, 1, {node}, 2) -> false
|
15637
|
+
* console.log(0, {node}) -> true
|
15638
|
+
*/
|
15639
|
+
function is_used_in_expression(tw) {
|
15640
|
+
for (let p = -1, node, parent; node = tw.parent(p), parent = tw.parent(p + 1); p++) {
|
15641
|
+
if (parent instanceof AST_Sequence) {
|
15642
|
+
const nth_expression = parent.expressions.indexOf(node);
|
15643
|
+
if (nth_expression !== parent.expressions.length - 1) {
|
15644
|
+
// Detect (0, x.noThis)() constructs
|
15645
|
+
const grandparent = tw.parent(p + 2);
|
15646
|
+
if (
|
15647
|
+
parent.expressions.length > 2
|
15648
|
+
|| parent.expressions.length === 1
|
15649
|
+
|| !requires_sequence_to_maintain_binding(grandparent, parent, parent.expressions[1])
|
15650
|
+
) {
|
15651
|
+
return false;
|
15652
|
+
}
|
15653
|
+
return true;
|
15654
|
+
} else {
|
15655
|
+
continue;
|
15656
|
+
}
|
15657
|
+
}
|
15658
|
+
if (parent instanceof AST_Unary) {
|
15659
|
+
const op = parent.operator;
|
15660
|
+
if (op === "void") {
|
15661
|
+
return false;
|
15662
|
+
}
|
15663
|
+
if (op === "typeof" || op === "+" || op === "-" || op === "!" || op === "~") {
|
15664
|
+
continue;
|
15665
|
+
}
|
15666
|
+
}
|
15667
|
+
return true;
|
15668
|
+
}
|
15669
|
+
|
15670
|
+
return true;
|
15671
|
+
}
|
15672
|
+
|
15617
15673
|
/***********************************************************************
|
15618
15674
|
|
15619
15675
|
A JavaScript tokenizer / parser / beautifier / compressor.
|
package/lib/compress/common.js
CHANGED
@@ -226,7 +226,17 @@ export function has_break_or_continue(loop, parent) {
|
|
226
226
|
// func(something) because that changes the meaning of
|
227
227
|
// the func (becomes lexical instead of global).
|
228
228
|
export function maintain_this_binding(parent, orig, val) {
|
229
|
-
if (
|
229
|
+
if (requires_sequence_to_maintain_binding(parent, orig, val)) {
|
230
|
+
const zero = make_node(AST_Number, orig, { value: 0 });
|
231
|
+
return make_sequence(orig, [ zero, val ]);
|
232
|
+
} else {
|
233
|
+
return val;
|
234
|
+
}
|
235
|
+
}
|
236
|
+
|
237
|
+
/** Detect (1, x.noThis)(), (0, eval)(), which need sequences */
|
238
|
+
export function requires_sequence_to_maintain_binding(parent, orig, val) {
|
239
|
+
return (
|
230
240
|
parent instanceof AST_UnaryPrefix && parent.operator == "delete"
|
231
241
|
|| parent instanceof AST_Call && parent.expression === orig
|
232
242
|
&& (
|
@@ -234,12 +244,7 @@ export function maintain_this_binding(parent, orig, val) {
|
|
234
244
|
|| val instanceof AST_PropAccess
|
235
245
|
|| val instanceof AST_SymbolRef && val.name == "eval"
|
236
246
|
)
|
237
|
-
)
|
238
|
-
const zero = make_node(AST_Number, orig, { value: 0 });
|
239
|
-
return make_sequence(orig, [ zero, val ]);
|
240
|
-
} else {
|
241
|
-
return val;
|
242
|
-
}
|
247
|
+
);
|
243
248
|
}
|
244
249
|
|
245
250
|
export function is_func_expr(node) {
|
@@ -63,6 +63,7 @@ import {
|
|
63
63
|
AST_Lambda,
|
64
64
|
AST_Number,
|
65
65
|
AST_Scope,
|
66
|
+
AST_Sequence,
|
66
67
|
AST_SimpleStatement,
|
67
68
|
AST_SymbolBlockDeclaration,
|
68
69
|
AST_SymbolCatch,
|
@@ -101,6 +102,7 @@ import {
|
|
101
102
|
is_empty,
|
102
103
|
is_ref_of,
|
103
104
|
can_be_evicted_from_block,
|
105
|
+
requires_sequence_to_maintain_binding,
|
104
106
|
} from "./common.js";
|
105
107
|
|
106
108
|
const r_keep_assign = /keep_assign/;
|
@@ -231,7 +233,11 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
|
|
231
233
|
var in_use = in_use_ids.has(def.id);
|
232
234
|
if (node instanceof AST_Assign) {
|
233
235
|
if (!in_use || fixed_ids.has(def.id) && fixed_ids.get(def.id) !== node) {
|
234
|
-
|
236
|
+
const assignee = node.right.transform(tt);
|
237
|
+
if (!in_use && !assignee.has_side_effects(compressor) && !is_used_in_expression(tt)) {
|
238
|
+
return in_list ? MAP.skip : make_node(AST_Number, node, { value: 0 });
|
239
|
+
}
|
240
|
+
return maintain_this_binding(parent, node, assignee);
|
235
241
|
}
|
236
242
|
} else if (!in_use) {
|
237
243
|
return in_list ? MAP.skip : make_node(AST_Number, node, { value: 0 });
|
@@ -438,6 +444,14 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
|
|
438
444
|
scope = save_scope;
|
439
445
|
return node;
|
440
446
|
}
|
447
|
+
},
|
448
|
+
function after(node, in_list) {
|
449
|
+
if (node instanceof AST_Sequence) {
|
450
|
+
switch (node.expressions.length) {
|
451
|
+
case 0: return in_list ? MAP.skip : make_node(AST_Number, node, { value: 0 });
|
452
|
+
case 1: return node.expressions[0];
|
453
|
+
}
|
454
|
+
}
|
441
455
|
}
|
442
456
|
);
|
443
457
|
|
@@ -484,3 +498,41 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
|
|
484
498
|
}
|
485
499
|
});
|
486
500
|
|
501
|
+
/**
|
502
|
+
* Check if a node may be used by the expression it's in
|
503
|
+
* void (0, 1, {node}, 2) -> false
|
504
|
+
* console.log(0, {node}) -> true
|
505
|
+
*/
|
506
|
+
function is_used_in_expression(tw) {
|
507
|
+
for (let p = -1, node, parent; node = tw.parent(p), parent = tw.parent(p + 1); p++) {
|
508
|
+
if (parent instanceof AST_Sequence) {
|
509
|
+
const nth_expression = parent.expressions.indexOf(node);
|
510
|
+
if (nth_expression !== parent.expressions.length - 1) {
|
511
|
+
// Detect (0, x.noThis)() constructs
|
512
|
+
const grandparent = tw.parent(p + 2);
|
513
|
+
if (
|
514
|
+
parent.expressions.length > 2
|
515
|
+
|| parent.expressions.length === 1
|
516
|
+
|| !requires_sequence_to_maintain_binding(grandparent, parent, parent.expressions[1])
|
517
|
+
) {
|
518
|
+
return false;
|
519
|
+
}
|
520
|
+
return true;
|
521
|
+
} else {
|
522
|
+
continue;
|
523
|
+
}
|
524
|
+
}
|
525
|
+
if (parent instanceof AST_Unary) {
|
526
|
+
const op = parent.operator;
|
527
|
+
if (op === "void") {
|
528
|
+
return false;
|
529
|
+
}
|
530
|
+
if (op === "typeof" || op === "+" || op === "-" || op === "!" || op === "~") {
|
531
|
+
continue;
|
532
|
+
}
|
533
|
+
}
|
534
|
+
return true;
|
535
|
+
}
|
536
|
+
|
537
|
+
return true;
|
538
|
+
}
|