terser 5.3.1 → 5.3.5

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,24 @@
1
1
  # Changelog
2
2
 
3
+ ## v5.3.5
4
+
5
+ - Avoid moving named functions into default exports.
6
+ - Enabled transform() for chain expressions. This allows AST transformers to reach inside chain expressions.
7
+
8
+ ## v5.3.4
9
+
10
+ - Fixed a crash when hoisting (with `hoist_vars`) a destructuring variable declaration
11
+
12
+ ## v5.3.3
13
+
14
+ - `source-map` library has been updated, bringing memory usage and CPU time improvements when reading input source maps (the SourceMapConsumer is now WASM based).
15
+ - The `wrap_func_args` option now also wraps arrow functions, as opposed to only function expressions.
16
+
17
+ ## v5.3.2
18
+
19
+ - Prevented spread operations from being expanded when the expanded array/object contains getters, setters, or array holes.
20
+ - Fixed _very_ slow self-recursion in some cases of removing extraneous parentheses from `+` operations.
21
+
3
22
  ## v5.3.1
4
23
 
5
24
  - An issue with destructuring declarations when `pure_getters` is enabled has been fixed
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
+ });
@@ -5363,6 +5363,10 @@ def_transform(AST_Sub, function(self, tw) {
5363
5363
  self.property = self.property.transform(tw);
5364
5364
  });
5365
5365
 
5366
+ def_transform(AST_Chain, function(self, tw) {
5367
+ self.expression = self.expression.transform(tw);
5368
+ });
5369
+
5366
5370
  def_transform(AST_Yield, function(self, tw) {
5367
5371
  if (self.expression) self.expression = self.expression.transform(tw);
5368
5372
  });
@@ -7422,6 +7426,14 @@ function OutputStream(options) {
7422
7426
 
7423
7427
  PARENS(AST_Arrow, function(output) {
7424
7428
  var p = output.parent();
7429
+
7430
+ if (
7431
+ output.option("wrap_func_args")
7432
+ && p instanceof AST_Call
7433
+ && p.args.includes(this)
7434
+ ) {
7435
+ return true;
7436
+ }
7425
7437
  return p instanceof AST_PropAccess && p.expression === this;
7426
7438
  });
7427
7439
 
@@ -14234,9 +14246,12 @@ AST_Scope.DEFMETHOD("hoist_declarations", function(compressor) {
14234
14246
  hoisted.push(node);
14235
14247
  return make_node(AST_EmptyStatement, node);
14236
14248
  }
14237
- if (hoist_vars && node instanceof AST_Var) {
14249
+ if (
14250
+ hoist_vars
14251
+ && node instanceof AST_Var
14252
+ && !node.definitions.some(def => def.name instanceof AST_Destructuring)
14253
+ ) {
14238
14254
  node.definitions.forEach(function(def) {
14239
- if (def.name instanceof AST_Destructuring) return;
14240
14255
  vars.set(def.name.name, def);
14241
14256
  ++vars_found;
14242
14257
  });
@@ -14316,8 +14331,7 @@ AST_Scope.DEFMETHOD("hoist_declarations", function(compressor) {
14316
14331
  continue;
14317
14332
  }
14318
14333
  if (self.body[i] instanceof AST_BlockStatement) {
14319
- var tmp = [ i, 1 ].concat(self.body[i].body);
14320
- self.body.splice.apply(self.body, tmp);
14334
+ self.body.splice(i, 1, ...self.body[i].body);
14321
14335
  continue;
14322
14336
  }
14323
14337
  break;
@@ -15063,10 +15077,12 @@ AST_Definitions.DEFMETHOD("remove_initializers", function() {
15063
15077
 
15064
15078
  AST_Definitions.DEFMETHOD("to_assignments", function(compressor) {
15065
15079
  var reduce_vars = compressor.option("reduce_vars");
15066
- var assignments = this.definitions.reduce(function(a, def) {
15067
- if (def.value && !(def.name instanceof AST_Destructuring)) {
15080
+ var assignments = [];
15081
+
15082
+ for (const def of this.definitions) {
15083
+ if (def.value) {
15068
15084
  var name = make_node(AST_SymbolRef, def.name, def.name);
15069
- a.push(make_node(AST_Assign, def, {
15085
+ assignments.push(make_node(AST_Assign, def, {
15070
15086
  operator : "=",
15071
15087
  left : name,
15072
15088
  right : def.value
@@ -15081,13 +15097,13 @@ AST_Definitions.DEFMETHOD("to_assignments", function(compressor) {
15081
15097
  var var_ = make_node(AST_Var, def, {
15082
15098
  definitions: [ varDef ]
15083
15099
  });
15084
- a.push(var_);
15100
+ assignments.push(var_);
15085
15101
  }
15086
- def = def.name.definition();
15087
- def.eliminated++;
15088
- def.replaced--;
15089
- return a;
15090
- }, []);
15102
+ const thedef = def.name.definition();
15103
+ thedef.eliminated++;
15104
+ thedef.replaced--;
15105
+ }
15106
+
15091
15107
  if (assignments.length == 0) return null;
15092
15108
  return make_sequence(this, assignments);
15093
15109
  });
@@ -15114,7 +15130,7 @@ function retain_top_func(fn, compressor) {
15114
15130
  def_optimize(AST_Call, function(self, compressor) {
15115
15131
  var exp = self.expression;
15116
15132
  var fn = exp;
15117
- inline_array_like_spread(self, compressor, self.args);
15133
+ inline_array_like_spread(self.args);
15118
15134
  var simple_args = self.args.every((arg) =>
15119
15135
  !(arg instanceof AST_Expansion)
15120
15136
  );
@@ -16074,7 +16090,7 @@ def_optimize(AST_Binary, function(self, compressor) {
16074
16090
  && self.left.left.getValue() == ""
16075
16091
  && self.right.is_string(compressor)) {
16076
16092
  self.left = self.left.right;
16077
- return self.transform(compressor);
16093
+ return self;
16078
16094
  }
16079
16095
  }
16080
16096
  if (compressor.option("evaluate")) {
@@ -16173,25 +16189,6 @@ def_optimize(AST_Binary, function(self, compressor) {
16173
16189
  var associative = true;
16174
16190
  switch (self.operator) {
16175
16191
  case "+":
16176
- // "foo" + ("bar" + x) => "foobar" + x
16177
- if (self.left instanceof AST_Constant
16178
- && self.right instanceof AST_Binary
16179
- && self.right.operator == "+"
16180
- && self.right.is_string(compressor)) {
16181
- var binary = make_node(AST_Binary, self, {
16182
- operator: "+",
16183
- left: self.left,
16184
- right: self.right.left,
16185
- });
16186
- var l = binary.optimize(compressor);
16187
- if (binary !== l) {
16188
- self = make_node(AST_Binary, self, {
16189
- operator: "+",
16190
- left: l,
16191
- right: self.right.right
16192
- });
16193
- }
16194
- }
16195
16192
  // (x + "foo") + "bar" => x + "foobar"
16196
16193
  if (self.right instanceof AST_Constant
16197
16194
  && self.left instanceof AST_Binary
@@ -16400,10 +16397,10 @@ def_optimize(AST_Binary, function(self, compressor) {
16400
16397
  ) {
16401
16398
  self.left = make_node(AST_Binary, self.left, {
16402
16399
  operator : self.operator,
16403
- left : self.left,
16404
- right : self.right.left
16400
+ left : self.left.transform(compressor),
16401
+ right : self.right.left.transform(compressor)
16405
16402
  });
16406
- self.right = self.right.right;
16403
+ self.right = self.right.right.transform(compressor);
16407
16404
  return self.transform(compressor);
16408
16405
  }
16409
16406
  var ev = self.evaluate(compressor);
@@ -16476,7 +16473,9 @@ def_optimize(AST_SymbolRef, function(self, compressor) {
16476
16473
  && !(parent instanceof AST_Call
16477
16474
  && (parent.is_expr_pure(compressor))
16478
16475
  || has_annotation(parent, _NOINLINE))
16479
- && !(fixed instanceof AST_Defun && parent instanceof AST_Export);
16476
+ && !(parent instanceof AST_Export
16477
+ && fixed instanceof AST_Lambda
16478
+ && fixed.name);
16480
16479
 
16481
16480
  if (single_use && (fixed instanceof AST_Lambda || fixed instanceof AST_Class)) {
16482
16481
  if (retain_top_func(fixed, compressor)) {
@@ -17420,12 +17419,15 @@ function literals_in_boolean_context(self, compressor) {
17420
17419
  return self;
17421
17420
  }
17422
17421
 
17423
- function inline_array_like_spread(self, compressor, elements) {
17422
+ function inline_array_like_spread(elements) {
17424
17423
  for (var i = 0; i < elements.length; i++) {
17425
17424
  var el = elements[i];
17426
17425
  if (el instanceof AST_Expansion) {
17427
17426
  var expr = el.expression;
17428
- if ( expr instanceof AST_Array) {
17427
+ if (
17428
+ expr instanceof AST_Array
17429
+ && !expr.elements.some(elm => elm instanceof AST_Hole)
17430
+ ) {
17429
17431
  elements.splice(i, 1, ...expr.elements);
17430
17432
  // Step back one, as the element at i is now new.
17431
17433
  i--;
@@ -17434,7 +17436,6 @@ function inline_array_like_spread(self, compressor, elements) {
17434
17436
  // We therefore can’t optimize anything else, unlike with object spread.
17435
17437
  }
17436
17438
  }
17437
- return self;
17438
17439
  }
17439
17440
 
17440
17441
  def_optimize(AST_Array, function(self, compressor) {
@@ -17442,21 +17443,20 @@ def_optimize(AST_Array, function(self, compressor) {
17442
17443
  if (optimized !== self) {
17443
17444
  return optimized;
17444
17445
  }
17445
- return inline_array_like_spread(self, compressor, self.elements);
17446
+ inline_array_like_spread(self.elements);
17447
+ return self;
17446
17448
  });
17447
17449
 
17448
- def_optimize(AST_Object, function(self, compressor) {
17449
- var optimized = literals_in_boolean_context(self, compressor);
17450
- if (optimized !== self) {
17451
- return optimized;
17452
- }
17453
- var props = self.properties;
17450
+ function inline_object_prop_spread(props) {
17454
17451
  for (var i = 0; i < props.length; i++) {
17455
17452
  var prop = props[i];
17456
17453
  if (prop instanceof AST_Expansion) {
17457
- var expr = prop.expression;
17458
- if (expr instanceof AST_Object) {
17459
- props.splice.apply(props, [i, 1].concat(prop.expression.properties));
17454
+ const expr = prop.expression;
17455
+ if (
17456
+ expr instanceof AST_Object
17457
+ && expr.properties.every(prop => prop instanceof AST_ObjectKeyVal)
17458
+ ) {
17459
+ props.splice(i, 1, ...expr.properties);
17460
17460
  // Step back one, as the property at i is now new.
17461
17461
  i--;
17462
17462
  } else if (expr instanceof AST_Constant
@@ -17468,6 +17468,14 @@ def_optimize(AST_Object, function(self, compressor) {
17468
17468
  }
17469
17469
  }
17470
17470
  }
17471
+ }
17472
+
17473
+ def_optimize(AST_Object, function(self, compressor) {
17474
+ var optimized = literals_in_boolean_context(self, compressor);
17475
+ if (optimized !== self) {
17476
+ return optimized;
17477
+ }
17478
+ inline_object_prop_spread(self.properties);
17471
17479
  return self;
17472
17480
  });
17473
17481
 
@@ -17756,7 +17764,7 @@ def_optimize(AST_Destructuring, function(self, compressor) {
17756
17764
  ***********************************************************************/
17757
17765
 
17758
17766
  // a small wrapper around fitzgen's source-map library
17759
- function SourceMap(options) {
17767
+ async function SourceMap(options) {
17760
17768
  options = defaults(options, {
17761
17769
  file : null,
17762
17770
  root : null,
@@ -17765,13 +17773,15 @@ function SourceMap(options) {
17765
17773
  orig_line_diff : 0,
17766
17774
  dest_line_diff : 0,
17767
17775
  });
17776
+
17777
+ var orig_map;
17768
17778
  var generator = new MOZ_SourceMap.SourceMapGenerator({
17769
17779
  file : options.file,
17770
17780
  sourceRoot : options.root
17771
17781
  });
17772
- var orig_map = options.orig && new MOZ_SourceMap.SourceMapConsumer(options.orig);
17773
17782
 
17774
- if (orig_map) {
17783
+ if (options.orig) {
17784
+ orig_map = await new MOZ_SourceMap.SourceMapConsumer(options.orig);
17775
17785
  orig_map.sources.forEach(function(source) {
17776
17786
  var sourceContent = orig_map.sourceContentFor(source, true);
17777
17787
  if (sourceContent) {
@@ -17801,10 +17811,16 @@ function SourceMap(options) {
17801
17811
  name : name
17802
17812
  });
17803
17813
  }
17814
+
17804
17815
  return {
17805
17816
  add : add,
17806
17817
  get : function() { return generator; },
17807
- toString : function() { return JSON.stringify(generator.toJSON()); }
17818
+ toString : function() { return generator.toString(); },
17819
+ destroy : function () {
17820
+ if (orig_map && orig_map.destroy) {
17821
+ orig_map.destroy();
17822
+ }
17823
+ }
17808
17824
  };
17809
17825
  }
17810
17826
 
@@ -26055,10 +26071,7 @@ async function minify(files, options) {
26055
26071
  }
26056
26072
  if (!HOP(options.format, "code") || options.format.code) {
26057
26073
  if (options.sourceMap) {
26058
- if (typeof options.sourceMap.content == "string") {
26059
- options.sourceMap.content = JSON.parse(options.sourceMap.content);
26060
- }
26061
- options.format.source_map = SourceMap({
26074
+ options.format.source_map = await SourceMap({
26062
26075
  file: options.sourceMap.filename,
26063
26076
  orig: options.sourceMap.content,
26064
26077
  root: options.sourceMap.root
@@ -26096,6 +26109,9 @@ async function minify(files, options) {
26096
26109
  options.nameCache.props = cache_to_json(options.mangle.properties.cache);
26097
26110
  }
26098
26111
  }
26112
+ if (options.format && options.format.source_map) {
26113
+ options.format.source_map.destroy();
26114
+ }
26099
26115
  if (timings) {
26100
26116
  timings.end = Date.now();
26101
26117
  result.timings = {