terser 5.3.0 → 5.3.4

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 CHANGED
@@ -1,5 +1,25 @@
1
1
  # Changelog
2
2
 
3
+ ## v5.3.4
4
+
5
+ - Fixed a crash when hoisting (with `hoist_vars`) a destructuring variable declaration
6
+
7
+ ## v5.3.3
8
+
9
+ - `source-map` library has been updated, bringing memory usage and CPU time improvements when reading input source maps (the SourceMapConsumer is now WASM based).
10
+ - The `wrap_func_args` option now also wraps arrow functions, as opposed to only function expressions.
11
+
12
+ ## v5.3.2
13
+
14
+ - Prevented spread operations from being expanded when the expanded array/object contains getters, setters, or array holes.
15
+ - Fixed _very_ slow self-recursion in some cases of removing extraneous parentheses from `+` operations.
16
+
17
+ ## v5.3.1
18
+
19
+ - An issue with destructuring declarations when `pure_getters` is enabled has been fixed
20
+ - Fixed a crash when chain expressions need to be shallowly compared
21
+ - Made inlining functions more conservative to make sure a function that contains a reference to itself isn't moved into a place that can create multiple instances of itself.
22
+
3
23
  ## v5.3.0
4
24
 
5
25
  - Fixed a crash when compressing object spreads in some cases
package/bin/terser.mjs ADDED
@@ -0,0 +1,21 @@
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
+ });
@@ -7422,6 +7422,14 @@ function OutputStream(options) {
7422
7422
 
7423
7423
  PARENS(AST_Arrow, function(output) {
7424
7424
  var p = output.parent();
7425
+
7426
+ if (
7427
+ output.option("wrap_func_args")
7428
+ && p instanceof AST_Call
7429
+ && p.args.includes(this)
7430
+ ) {
7431
+ return true;
7432
+ }
7425
7433
  return p instanceof AST_PropAccess && p.expression === this;
7426
7434
  });
7427
7435
 
@@ -8895,6 +8903,8 @@ AST_Sequence.prototype.shallow_cmp = pass_through;
8895
8903
 
8896
8904
  AST_PropAccess.prototype.shallow_cmp = pass_through;
8897
8905
 
8906
+ AST_Chain.prototype.shallow_cmp = pass_through;
8907
+
8898
8908
  AST_Dot.prototype.shallow_cmp = mkshallow({
8899
8909
  property: "eq"
8900
8910
  });
@@ -14232,9 +14242,12 @@ AST_Scope.DEFMETHOD("hoist_declarations", function(compressor) {
14232
14242
  hoisted.push(node);
14233
14243
  return make_node(AST_EmptyStatement, node);
14234
14244
  }
14235
- if (hoist_vars && node instanceof AST_Var) {
14245
+ if (
14246
+ hoist_vars
14247
+ && node instanceof AST_Var
14248
+ && !node.definitions.some(def => def.name instanceof AST_Destructuring)
14249
+ ) {
14236
14250
  node.definitions.forEach(function(def) {
14237
- if (def.name instanceof AST_Destructuring) return;
14238
14251
  vars.set(def.name.name, def);
14239
14252
  ++vars_found;
14240
14253
  });
@@ -14314,8 +14327,7 @@ AST_Scope.DEFMETHOD("hoist_declarations", function(compressor) {
14314
14327
  continue;
14315
14328
  }
14316
14329
  if (self.body[i] instanceof AST_BlockStatement) {
14317
- var tmp = [ i, 1 ].concat(self.body[i].body);
14318
- self.body.splice.apply(self.body, tmp);
14330
+ self.body.splice(i, 1, ...self.body[i].body);
14319
14331
  continue;
14320
14332
  }
14321
14333
  break;
@@ -15061,10 +15073,12 @@ AST_Definitions.DEFMETHOD("remove_initializers", function() {
15061
15073
 
15062
15074
  AST_Definitions.DEFMETHOD("to_assignments", function(compressor) {
15063
15075
  var reduce_vars = compressor.option("reduce_vars");
15064
- var assignments = this.definitions.reduce(function(a, def) {
15065
- if (def.value && !(def.name instanceof AST_Destructuring)) {
15076
+ var assignments = [];
15077
+
15078
+ for (const def of this.definitions) {
15079
+ if (def.value) {
15066
15080
  var name = make_node(AST_SymbolRef, def.name, def.name);
15067
- a.push(make_node(AST_Assign, def, {
15081
+ assignments.push(make_node(AST_Assign, def, {
15068
15082
  operator : "=",
15069
15083
  left : name,
15070
15084
  right : def.value
@@ -15079,13 +15093,13 @@ AST_Definitions.DEFMETHOD("to_assignments", function(compressor) {
15079
15093
  var var_ = make_node(AST_Var, def, {
15080
15094
  definitions: [ varDef ]
15081
15095
  });
15082
- a.push(var_);
15096
+ assignments.push(var_);
15083
15097
  }
15084
- def = def.name.definition();
15085
- def.eliminated++;
15086
- def.replaced--;
15087
- return a;
15088
- }, []);
15098
+ const thedef = def.name.definition();
15099
+ thedef.eliminated++;
15100
+ thedef.replaced--;
15101
+ }
15102
+
15089
15103
  if (assignments.length == 0) return null;
15090
15104
  return make_sequence(this, assignments);
15091
15105
  });
@@ -15112,7 +15126,7 @@ function retain_top_func(fn, compressor) {
15112
15126
  def_optimize(AST_Call, function(self, compressor) {
15113
15127
  var exp = self.expression;
15114
15128
  var fn = exp;
15115
- inline_array_like_spread(self, compressor, self.args);
15129
+ inline_array_like_spread(self.args);
15116
15130
  var simple_args = self.args.every((arg) =>
15117
15131
  !(arg instanceof AST_Expansion)
15118
15132
  );
@@ -16072,7 +16086,7 @@ def_optimize(AST_Binary, function(self, compressor) {
16072
16086
  && self.left.left.getValue() == ""
16073
16087
  && self.right.is_string(compressor)) {
16074
16088
  self.left = self.left.right;
16075
- return self.transform(compressor);
16089
+ return self;
16076
16090
  }
16077
16091
  }
16078
16092
  if (compressor.option("evaluate")) {
@@ -16171,25 +16185,6 @@ def_optimize(AST_Binary, function(self, compressor) {
16171
16185
  var associative = true;
16172
16186
  switch (self.operator) {
16173
16187
  case "+":
16174
- // "foo" + ("bar" + x) => "foobar" + x
16175
- if (self.left instanceof AST_Constant
16176
- && self.right instanceof AST_Binary
16177
- && self.right.operator == "+"
16178
- && self.right.is_string(compressor)) {
16179
- var binary = make_node(AST_Binary, self, {
16180
- operator: "+",
16181
- left: self.left,
16182
- right: self.right.left,
16183
- });
16184
- var l = binary.optimize(compressor);
16185
- if (binary !== l) {
16186
- self = make_node(AST_Binary, self, {
16187
- operator: "+",
16188
- left: l,
16189
- right: self.right.right
16190
- });
16191
- }
16192
- }
16193
16188
  // (x + "foo") + "bar" => x + "foobar"
16194
16189
  if (self.right instanceof AST_Constant
16195
16190
  && self.left instanceof AST_Binary
@@ -16398,10 +16393,10 @@ def_optimize(AST_Binary, function(self, compressor) {
16398
16393
  ) {
16399
16394
  self.left = make_node(AST_Binary, self.left, {
16400
16395
  operator : self.operator,
16401
- left : self.left,
16402
- right : self.right.left
16396
+ left : self.left.transform(compressor),
16397
+ right : self.right.left.transform(compressor)
16403
16398
  });
16404
- self.right = self.right.right;
16399
+ self.right = self.right.right.transform(compressor);
16405
16400
  return self.transform(compressor);
16406
16401
  }
16407
16402
  var ev = self.evaluate(compressor);
@@ -16504,7 +16499,8 @@ def_optimize(AST_SymbolRef, function(self, compressor) {
16504
16499
  && !scope_encloses_variables_in_this_scope(nearest_scope, fixed)
16505
16500
  || parent instanceof AST_Call
16506
16501
  && parent.expression === self
16507
- && !scope_encloses_variables_in_this_scope(nearest_scope, fixed);
16502
+ && !scope_encloses_variables_in_this_scope(nearest_scope, fixed)
16503
+ && !(fixed.name && fixed.name.definition().recursive_refs > 0);
16508
16504
  }
16509
16505
  if (single_use && fixed instanceof AST_Class) {
16510
16506
  const extends_inert = !fixed.extends
@@ -17417,12 +17413,15 @@ function literals_in_boolean_context(self, compressor) {
17417
17413
  return self;
17418
17414
  }
17419
17415
 
17420
- function inline_array_like_spread(self, compressor, elements) {
17416
+ function inline_array_like_spread(elements) {
17421
17417
  for (var i = 0; i < elements.length; i++) {
17422
17418
  var el = elements[i];
17423
17419
  if (el instanceof AST_Expansion) {
17424
17420
  var expr = el.expression;
17425
- if ( expr instanceof AST_Array) {
17421
+ if (
17422
+ expr instanceof AST_Array
17423
+ && !expr.elements.some(elm => elm instanceof AST_Hole)
17424
+ ) {
17426
17425
  elements.splice(i, 1, ...expr.elements);
17427
17426
  // Step back one, as the element at i is now new.
17428
17427
  i--;
@@ -17431,7 +17430,6 @@ function inline_array_like_spread(self, compressor, elements) {
17431
17430
  // We therefore can’t optimize anything else, unlike with object spread.
17432
17431
  }
17433
17432
  }
17434
- return self;
17435
17433
  }
17436
17434
 
17437
17435
  def_optimize(AST_Array, function(self, compressor) {
@@ -17439,21 +17437,20 @@ def_optimize(AST_Array, function(self, compressor) {
17439
17437
  if (optimized !== self) {
17440
17438
  return optimized;
17441
17439
  }
17442
- return inline_array_like_spread(self, compressor, self.elements);
17440
+ inline_array_like_spread(self.elements);
17441
+ return self;
17443
17442
  });
17444
17443
 
17445
- def_optimize(AST_Object, function(self, compressor) {
17446
- var optimized = literals_in_boolean_context(self, compressor);
17447
- if (optimized !== self) {
17448
- return optimized;
17449
- }
17450
- var props = self.properties;
17444
+ function inline_object_prop_spread(props) {
17451
17445
  for (var i = 0; i < props.length; i++) {
17452
17446
  var prop = props[i];
17453
17447
  if (prop instanceof AST_Expansion) {
17454
- var expr = prop.expression;
17455
- if (expr instanceof AST_Object) {
17456
- props.splice.apply(props, [i, 1].concat(prop.expression.properties));
17448
+ const expr = prop.expression;
17449
+ if (
17450
+ expr instanceof AST_Object
17451
+ && expr.properties.every(prop => prop instanceof AST_ObjectKeyVal)
17452
+ ) {
17453
+ props.splice(i, 1, ...expr.properties);
17457
17454
  // Step back one, as the property at i is now new.
17458
17455
  i--;
17459
17456
  } else if (expr instanceof AST_Constant
@@ -17465,6 +17462,14 @@ def_optimize(AST_Object, function(self, compressor) {
17465
17462
  }
17466
17463
  }
17467
17464
  }
17465
+ }
17466
+
17467
+ def_optimize(AST_Object, function(self, compressor) {
17468
+ var optimized = literals_in_boolean_context(self, compressor);
17469
+ if (optimized !== self) {
17470
+ return optimized;
17471
+ }
17472
+ inline_object_prop_spread(self.properties);
17468
17473
  return self;
17469
17474
  });
17470
17475
 
@@ -17664,7 +17669,8 @@ def_optimize(AST_Destructuring, function(self, compressor) {
17664
17669
  && compressor.option("unused")
17665
17670
  && !self.is_array
17666
17671
  && Array.isArray(self.names)
17667
- && !is_destructuring_export_decl(compressor)) {
17672
+ && !is_destructuring_export_decl(compressor)
17673
+ && !(self.names[self.names.length - 1] instanceof AST_Expansion)) {
17668
17674
  var keep = [];
17669
17675
  for (var i = 0; i < self.names.length; i++) {
17670
17676
  var elem = self.names[i];
@@ -17752,7 +17758,7 @@ def_optimize(AST_Destructuring, function(self, compressor) {
17752
17758
  ***********************************************************************/
17753
17759
 
17754
17760
  // a small wrapper around fitzgen's source-map library
17755
- function SourceMap(options) {
17761
+ async function SourceMap(options) {
17756
17762
  options = defaults(options, {
17757
17763
  file : null,
17758
17764
  root : null,
@@ -17761,13 +17767,15 @@ function SourceMap(options) {
17761
17767
  orig_line_diff : 0,
17762
17768
  dest_line_diff : 0,
17763
17769
  });
17770
+
17771
+ var orig_map;
17764
17772
  var generator = new MOZ_SourceMap.SourceMapGenerator({
17765
17773
  file : options.file,
17766
17774
  sourceRoot : options.root
17767
17775
  });
17768
- var orig_map = options.orig && new MOZ_SourceMap.SourceMapConsumer(options.orig);
17769
17776
 
17770
- if (orig_map) {
17777
+ if (options.orig) {
17778
+ orig_map = await new MOZ_SourceMap.SourceMapConsumer(options.orig);
17771
17779
  orig_map.sources.forEach(function(source) {
17772
17780
  var sourceContent = orig_map.sourceContentFor(source, true);
17773
17781
  if (sourceContent) {
@@ -17797,10 +17805,16 @@ function SourceMap(options) {
17797
17805
  name : name
17798
17806
  });
17799
17807
  }
17808
+
17800
17809
  return {
17801
17810
  add : add,
17802
17811
  get : function() { return generator; },
17803
- toString : function() { return JSON.stringify(generator.toJSON()); }
17812
+ toString : function() { return generator.toString(); },
17813
+ destroy : function () {
17814
+ if (orig_map && orig_map.destroy) {
17815
+ orig_map.destroy();
17816
+ }
17817
+ }
17804
17818
  };
17805
17819
  }
17806
17820
 
@@ -26051,10 +26065,7 @@ async function minify(files, options) {
26051
26065
  }
26052
26066
  if (!HOP(options.format, "code") || options.format.code) {
26053
26067
  if (options.sourceMap) {
26054
- if (typeof options.sourceMap.content == "string") {
26055
- options.sourceMap.content = JSON.parse(options.sourceMap.content);
26056
- }
26057
- options.format.source_map = SourceMap({
26068
+ options.format.source_map = await SourceMap({
26058
26069
  file: options.sourceMap.filename,
26059
26070
  orig: options.sourceMap.content,
26060
26071
  root: options.sourceMap.root
@@ -26092,6 +26103,9 @@ async function minify(files, options) {
26092
26103
  options.nameCache.props = cache_to_json(options.mangle.properties.cache);
26093
26104
  }
26094
26105
  }
26106
+ if (options.format && options.format.source_map) {
26107
+ options.format.source_map.destroy();
26108
+ }
26095
26109
  if (timings) {
26096
26110
  timings.end = Date.now();
26097
26111
  result.timings = {