terser 5.19.0 → 5.19.2

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,13 @@
1
1
  # Changelog
2
2
 
3
+ ## v5.19.2
4
+ - fix performance hit from avoiding HTML comments in the output
5
+
6
+ ## v5.19.1
7
+ - Better avoid outputting `</script>` and HTML comments.
8
+ - Fix unused variables in class static blocks not being dropped correctly.
9
+ - Fix sourcemap names of methods that are `async` or `static`
10
+
3
11
  ## v5.19.0
4
12
  - Allow `/*@__MANGLE_PROP__*/` annotation in `object.property`, in addition to property declarations.
5
13
 
@@ -9162,10 +9162,12 @@ function OutputStream(options) {
9162
9162
  mappings.forEach(function(mapping) {
9163
9163
  try {
9164
9164
  let { name, token } = mapping;
9165
- if (token.type == "name" || token.type === "privatename") {
9166
- name = token.value;
9167
- } else if (name instanceof AST_Symbol) {
9168
- name = token.type === "string" ? token.value : name.name;
9165
+ if (name !== false) {
9166
+ if (token.type == "name" || token.type === "privatename") {
9167
+ name = token.value;
9168
+ } else if (name instanceof AST_Symbol) {
9169
+ name = token.type === "string" ? token.value : name.name;
9170
+ }
9169
9171
  }
9170
9172
  options.source_map.add(
9171
9173
  mapping.token.file,
@@ -10725,6 +10727,10 @@ function OutputStream(options) {
10725
10727
  });
10726
10728
  DEFPRINT(AST_UnaryPrefix, function(self, output) {
10727
10729
  var op = self.operator;
10730
+ if (op === "--" && output.last().endsWith("!")) {
10731
+ // avoid printing "<!--"
10732
+ output.print(" ");
10733
+ }
10728
10734
  output.print(op);
10729
10735
  if (/^[a-z]/i.test(op)
10730
10736
  || (/[+-]$/.test(op)
@@ -10742,8 +10748,7 @@ function OutputStream(options) {
10742
10748
  var op = self.operator;
10743
10749
  self.left.print(output);
10744
10750
  if (op[0] == ">" /* ">>" ">>>" ">" ">=" */
10745
- && self.left instanceof AST_UnaryPostfix
10746
- && self.left.operator == "--") {
10751
+ && output.last().endsWith("--")) {
10747
10752
  // space is mandatory to avoid outputting -->
10748
10753
  output.print(" ");
10749
10754
  } else {
@@ -10751,17 +10756,7 @@ function OutputStream(options) {
10751
10756
  output.space();
10752
10757
  }
10753
10758
  output.print(op);
10754
- if ((op == "<" || op == "<<")
10755
- && self.right instanceof AST_UnaryPrefix
10756
- && self.right.operator == "!"
10757
- && self.right.expression instanceof AST_UnaryPrefix
10758
- && self.right.expression.operator == "--") {
10759
- // space is mandatory to avoid outputting <!--
10760
- output.print(" ");
10761
- } else {
10762
- // the space is optional depending on "beautify"
10763
- output.space();
10764
- }
10759
+ output.space();
10765
10760
  self.right.print(output);
10766
10761
  });
10767
10762
  DEFPRINT(AST_Conditional, function(self, output) {
@@ -10974,6 +10969,7 @@ function OutputStream(options) {
10974
10969
  if (self.key instanceof AST_SymbolMethod) {
10975
10970
  if (is_private) output.print("#");
10976
10971
  print_property_name(self.key.name, self.quote, output);
10972
+ self.key.add_source_map(output);
10977
10973
  } else {
10978
10974
  output.with_square(function() {
10979
10975
  self.key.print(output);
@@ -11062,12 +11058,18 @@ function OutputStream(options) {
11062
11058
  });
11063
11059
 
11064
11060
  const r_slash_script = /(<\s*\/\s*script)/i;
11061
+ const r_starts_with_script = /^\s*script/i;
11065
11062
  const slash_script_replace = (_, $1) => $1.replace("/", "\\/");
11066
11063
  DEFPRINT(AST_RegExp, function(self, output) {
11067
11064
  let { source, flags } = self.getValue();
11068
11065
  source = regexp_source_fix(source);
11069
11066
  flags = flags ? sort_regexp_flags(flags) : "";
11067
+
11068
+ // Avoid outputting end of script tag
11070
11069
  source = source.replace(r_slash_script, slash_script_replace);
11070
+ if (r_starts_with_script.test(source) && output.last().endsWith("<")) {
11071
+ output.print(" ");
11072
+ }
11071
11073
 
11072
11074
  output.print(output.to_utf8(`/${source}/${flags}`, false, true));
11073
11075
 
@@ -11191,8 +11193,22 @@ function OutputStream(options) {
11191
11193
  AST_ObjectSetter,
11192
11194
  AST_PrivateGetter,
11193
11195
  AST_PrivateSetter,
11196
+ AST_ConciseMethod,
11197
+ AST_PrivateMethod,
11198
+ ], function(output) {
11199
+ output.add_mapping(this.start, false /*name handled below*/);
11200
+ });
11201
+
11202
+ DEFMAP([
11203
+ AST_SymbolMethod,
11204
+ AST_SymbolPrivateProperty
11194
11205
  ], function(output) {
11195
- output.add_mapping(this.key.end, this.key.name);
11206
+ const tok_type = this.end && this.end.type;
11207
+ if (tok_type === "name" || tok_type === "privatename") {
11208
+ output.add_mapping(this.end, this.name);
11209
+ } else {
11210
+ output.add_mapping(this.end);
11211
+ }
11196
11212
  });
11197
11213
 
11198
11214
  DEFMAP([ AST_ObjectProperty ], function(output) {
@@ -15281,21 +15297,24 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
15281
15297
  }
15282
15298
  }
15283
15299
  }
15284
- if ((node instanceof AST_Defun || node instanceof AST_DefClass) && node !== self) {
15300
+ if (node instanceof AST_DefClass && node !== self) {
15301
+ const def = node.name.definition();
15302
+ descend(node, this);
15303
+ const keep_class = def.global && !drop_funcs || in_use_ids.has(def.id);
15304
+ if (!keep_class) {
15305
+ const kept = node.drop_side_effect_free(compressor);
15306
+ if (kept == null) {
15307
+ def.eliminated++;
15308
+ return in_list ? MAP.skip : make_node(AST_EmptyStatement, node);
15309
+ }
15310
+ return kept;
15311
+ }
15312
+ return node;
15313
+ }
15314
+ if (node instanceof AST_Defun && node !== self) {
15285
15315
  const def = node.name.definition();
15286
15316
  const keep = def.global && !drop_funcs || in_use_ids.has(def.id);
15287
15317
  if (!keep) {
15288
- // Class "extends" and static blocks may have side effects
15289
- if (node instanceof AST_Class) {
15290
- const kept = node.drop_side_effect_free(compressor);
15291
- if (kept !== node) {
15292
- def.eliminated++;
15293
- if (kept) return kept;
15294
- return in_list ? MAP.skip : make_node(AST_EmptyStatement, node);
15295
- } else {
15296
- return kept;
15297
- }
15298
- }
15299
15318
  def.eliminated++;
15300
15319
  return in_list ? MAP.skip : make_node(AST_EmptyStatement, node);
15301
15320
  }
@@ -273,21 +273,24 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
273
273
  }
274
274
  }
275
275
  }
276
- if ((node instanceof AST_Defun || node instanceof AST_DefClass) && node !== self) {
276
+ if (node instanceof AST_DefClass && node !== self) {
277
+ const def = node.name.definition();
278
+ descend(node, this);
279
+ const keep_class = def.global && !drop_funcs || in_use_ids.has(def.id);
280
+ if (!keep_class) {
281
+ const kept = node.drop_side_effect_free(compressor);
282
+ if (kept == null) {
283
+ def.eliminated++;
284
+ return in_list ? MAP.skip : make_node(AST_EmptyStatement, node);
285
+ }
286
+ return kept;
287
+ }
288
+ return node;
289
+ }
290
+ if (node instanceof AST_Defun && node !== self) {
277
291
  const def = node.name.definition();
278
292
  const keep = def.global && !drop_funcs || in_use_ids.has(def.id);
279
293
  if (!keep) {
280
- // Class "extends" and static blocks may have side effects
281
- if (node instanceof AST_Class) {
282
- const kept = node.drop_side_effect_free(compressor);
283
- if (kept !== node) {
284
- def.eliminated++;
285
- if (kept) return kept;
286
- return in_list ? MAP.skip : make_node(AST_EmptyStatement, node);
287
- } else {
288
- return kept;
289
- }
290
- }
291
294
  def.eliminated++;
292
295
  return in_list ? MAP.skip : make_node(AST_EmptyStatement, node);
293
296
  }
package/lib/output.js CHANGED
@@ -398,10 +398,12 @@ function OutputStream(options) {
398
398
  mappings.forEach(function(mapping) {
399
399
  try {
400
400
  let { name, token } = mapping;
401
- if (token.type == "name" || token.type === "privatename") {
402
- name = token.value;
403
- } else if (name instanceof AST_Symbol) {
404
- name = token.type === "string" ? token.value : name.name;
401
+ if (name !== false) {
402
+ if (token.type == "name" || token.type === "privatename") {
403
+ name = token.value;
404
+ } else if (name instanceof AST_Symbol) {
405
+ name = token.type === "string" ? token.value : name.name;
406
+ }
405
407
  }
406
408
  options.source_map.add(
407
409
  mapping.token.file,
@@ -1961,6 +1963,10 @@ function OutputStream(options) {
1961
1963
  });
1962
1964
  DEFPRINT(AST_UnaryPrefix, function(self, output) {
1963
1965
  var op = self.operator;
1966
+ if (op === "--" && output.last().endsWith("!")) {
1967
+ // avoid printing "<!--"
1968
+ output.print(" ");
1969
+ }
1964
1970
  output.print(op);
1965
1971
  if (/^[a-z]/i.test(op)
1966
1972
  || (/[+-]$/.test(op)
@@ -1978,8 +1984,7 @@ function OutputStream(options) {
1978
1984
  var op = self.operator;
1979
1985
  self.left.print(output);
1980
1986
  if (op[0] == ">" /* ">>" ">>>" ">" ">=" */
1981
- && self.left instanceof AST_UnaryPostfix
1982
- && self.left.operator == "--") {
1987
+ && output.last().endsWith("--")) {
1983
1988
  // space is mandatory to avoid outputting -->
1984
1989
  output.print(" ");
1985
1990
  } else {
@@ -1987,17 +1992,7 @@ function OutputStream(options) {
1987
1992
  output.space();
1988
1993
  }
1989
1994
  output.print(op);
1990
- if ((op == "<" || op == "<<")
1991
- && self.right instanceof AST_UnaryPrefix
1992
- && self.right.operator == "!"
1993
- && self.right.expression instanceof AST_UnaryPrefix
1994
- && self.right.expression.operator == "--") {
1995
- // space is mandatory to avoid outputting <!--
1996
- output.print(" ");
1997
- } else {
1998
- // the space is optional depending on "beautify"
1999
- output.space();
2000
- }
1995
+ output.space();
2001
1996
  self.right.print(output);
2002
1997
  });
2003
1998
  DEFPRINT(AST_Conditional, function(self, output) {
@@ -2210,6 +2205,7 @@ function OutputStream(options) {
2210
2205
  if (self.key instanceof AST_SymbolMethod) {
2211
2206
  if (is_private) output.print("#");
2212
2207
  print_property_name(self.key.name, self.quote, output);
2208
+ self.key.add_source_map(output);
2213
2209
  } else {
2214
2210
  output.with_square(function() {
2215
2211
  self.key.print(output);
@@ -2298,12 +2294,18 @@ function OutputStream(options) {
2298
2294
  });
2299
2295
 
2300
2296
  const r_slash_script = /(<\s*\/\s*script)/i;
2297
+ const r_starts_with_script = /^\s*script/i;
2301
2298
  const slash_script_replace = (_, $1) => $1.replace("/", "\\/");
2302
2299
  DEFPRINT(AST_RegExp, function(self, output) {
2303
2300
  let { source, flags } = self.getValue();
2304
2301
  source = regexp_source_fix(source);
2305
2302
  flags = flags ? sort_regexp_flags(flags) : "";
2303
+
2304
+ // Avoid outputting end of script tag
2306
2305
  source = source.replace(r_slash_script, slash_script_replace);
2306
+ if (r_starts_with_script.test(source) && output.last().endsWith("<")) {
2307
+ output.print(" ");
2308
+ }
2307
2309
 
2308
2310
  output.print(output.to_utf8(`/${source}/${flags}`, false, true));
2309
2311
 
@@ -2427,8 +2429,22 @@ function OutputStream(options) {
2427
2429
  AST_ObjectSetter,
2428
2430
  AST_PrivateGetter,
2429
2431
  AST_PrivateSetter,
2432
+ AST_ConciseMethod,
2433
+ AST_PrivateMethod,
2430
2434
  ], function(output) {
2431
- output.add_mapping(this.key.end, this.key.name);
2435
+ output.add_mapping(this.start, false /*name handled below*/);
2436
+ });
2437
+
2438
+ DEFMAP([
2439
+ AST_SymbolMethod,
2440
+ AST_SymbolPrivateProperty
2441
+ ], function(output) {
2442
+ const tok_type = this.end && this.end.type;
2443
+ if (tok_type === "name" || tok_type === "privatename") {
2444
+ output.add_mapping(this.end, this.name);
2445
+ } else {
2446
+ output.add_mapping(this.end);
2447
+ }
2432
2448
  });
2433
2449
 
2434
2450
  DEFMAP([ AST_ObjectProperty ], function(output) {
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "homepage": "https://terser.org",
5
5
  "author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
6
6
  "license": "BSD-2-Clause",
7
- "version": "5.19.0",
7
+ "version": "5.19.2",
8
8
  "engines": {
9
9
  "node": ">=10"
10
10
  },