terser 3.9.2 → 3.10.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.

Potentially problematic release.


This version of terser might be problematic. Click here for more details.

package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  terser
2
2
  ======
3
3
 
4
- [![Build Status](https://travis-ci.org/terser-js/terser.svg?branch=master)](https://travis-ci.org/terser-js/terser)
4
+ [![Build Status](https://travis-ci.org/terser-js/terser.svg?branch=master)](https://travis-ci.org/terser-js/terser) [![Coverage Status](https://coveralls.io/repos/github/terser-js/terser/badge.svg?branch=master)](https://coveralls.io/github/terser-js/terser?branch=master)
5
5
 
6
6
  A JavaScript parser, mangler/compressor and beautifier toolkit for ES6+.
7
7
 
@@ -127,7 +127,6 @@ a double dash to prevent input files being used as option arguments:
127
127
  for `mangle` and `output` options.
128
128
  By default `terser` will not work around
129
129
  Safari 10/11 bugs.
130
- --self Build Terser as a library (implies --wrap Terser)
131
130
  --source-map [options] Enable source map/specify source map options:
132
131
  `base` Path to compute relative paths from input files.
133
132
  `content` Input source map, useful if you're compressing
@@ -531,12 +530,13 @@ if (result.error) throw result.error;
531
530
  - `ie8` (default `false`) - set to `true` to support IE8.
532
531
 
533
532
  - `keep_classnames` (default: `undefined`) - pass `true` to prevent discarding or mangling
534
- of class names.
533
+ of class names. Pass a regular expression to only keep class names matching that regex.
535
534
 
536
535
  - `keep_fnames` (default: `false`) - pass `true` to prevent discarding or mangling
537
- of function names. Useful for code relying on `Function.prototype.name`. If the
538
- top level minify option `keep_classnames` is `undefined` it will be overridden with
539
- the value of the top level minify option `keep_fnames`.
536
+ of function names. Pass a regular expression to only keep class names matching that regex.
537
+ Useful for code relying on `Function.prototype.name`. If the top level minify option
538
+ `keep_classnames` is `undefined` it will be overridden with the value of the top level
539
+ minify option `keep_fnames`.
540
540
 
541
541
  - `safari10` (default: `false`) - pass `true` to work around Safari 10/11 bugs in
542
542
  loop scoping and `await`. See `safari10` options in [`mangle`](#mangle-options)
@@ -648,6 +648,9 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u
648
648
  - `booleans` (default: `true`) -- various optimizations for boolean context,
649
649
  for example `!!a ? b : c → a ? b : c`
650
650
 
651
+ - `booleans_as_integers` (default: `false`) -- Turn booleans into 0 and 1, also
652
+ makes comparisons with booleans use `==` and `!=` instead of `===` and `!==`.
653
+
651
654
  - `collapse_vars` (default: `true`) -- Collapse single-use non-constant variables,
652
655
  side effects permitting.
653
656
 
@@ -709,16 +712,17 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u
709
712
 
710
713
  - `join_vars` (default: `true`) -- join consecutive `var` statements
711
714
 
712
- - `keep_classnames` (default: `false`) -- Pass `true` to prevent the
713
- compressor from discarding class names. See also: the `keep_classnames`
714
- [mangle option](#mangle).
715
+ - `keep_classnames` (default: `false`) -- Pass `true` to prevent the compressor from
716
+ discarding class names. Pass a regular expression to only keep class names matching
717
+ that regex. See also: the `keep_classnames` [mangle option](#mangle).
715
718
 
716
719
  - `keep_fargs` (default: `true`) -- Prevents the compressor from discarding unused
717
720
  function arguments. You need this for code which relies on `Function.length`.
718
721
 
719
722
  - `keep_fnames` (default: `false`) -- Pass `true` to prevent the
720
- compressor from discarding function names. Useful for code relying on
721
- `Function.prototype.name`. See also: the `keep_fnames` [mangle option](#mangle).
723
+ compressor from discarding function names. Pass a regular expression to only keep
724
+ class names matching that regex. Useful for code relying on `Function.prototype.name`.
725
+ See also: the `keep_fnames` [mangle option](#mangle).
722
726
 
723
727
  - `keep_infinity` (default: `false`) -- Pass `true` to prevent `Infinity` from
724
728
  being compressed into `1/0`, which may cause performance issues on Chrome.
@@ -845,9 +849,11 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u
845
849
  where `eval` or `with` are used.
846
850
 
847
851
  - `keep_classnames` (default `false`) -- Pass `true` to not mangle class names.
852
+ Pass a regular expression to only keep class names matching that regex.
848
853
  See also: the `keep_classnames` [compress option](#compress-options).
849
854
 
850
855
  - `keep_fnames` (default `false`) -- Pass `true` to not mangle function names.
856
+ Pass a regular expression to only keep class names matching that regex.
851
857
  Useful for code relying on `Function.prototype.name`. See also: the `keep_fnames`
852
858
  [compress option](#compress-options).
853
859
 
package/bin/uglifyjs CHANGED
@@ -10,15 +10,14 @@ var info = require("../package.json");
10
10
  var path = require("path");
11
11
  var program = require("commander");
12
12
 
13
- var bundle_path = __dirname + "/../dist/browser.bundle.js";
14
- if (process.env.TERSER_DEBUG
15
- /* note: commander not initialized yet */
16
- && !/--help|--self/.test(process.argv.toString())
17
- && fs.existsSync(bundle_path)) {
18
- var UglifyJS = require(bundle_path);
19
- try {
20
- require("source-map-support").install();
21
- } catch (err) {}
13
+ var bundle_path = __dirname + "/../dist/bundle.js";
14
+ if (fs.existsSync(bundle_path)) {
15
+ var UglifyJS = require(bundle_path)
16
+ if (process.env.TERSER_DEBUG) {
17
+ try {
18
+ require("source-map-support").install();
19
+ } catch (err) {}
20
+ }
22
21
  } else {
23
22
  var UglifyJS = require("../tools/node.js");
24
23
  }
@@ -32,7 +31,7 @@ var options = {
32
31
  program.version(info.name + " " + info.version);
33
32
  program.parseArgv = program.parse;
34
33
  program.parse = undefined;
35
- if (process.argv.indexOf("ast") >= 0) program.helpInformation = UglifyJS.describe_ast;
34
+ if (process.argv.indexOf("ast") >= 0) program.helpInformation = describe_ast;
36
35
  else if (process.argv.indexOf("options") >= 0) program.helpInformation = function() {
37
36
  var text = [];
38
37
  var options = UglifyJS.default_options();
@@ -62,7 +61,6 @@ program.option("--name-cache <file>", "File to hold mangled name mappings.");
62
61
  program.option("--rename", "Force symbol expansion.");
63
62
  program.option("--no-rename", "Disable symbol expansion.");
64
63
  program.option("--safari10", "Support non-standard Safari 10.");
65
- program.option("--self", "Build Terser as a library (implies --wrap Terser)");
66
64
  program.option("--source-map [options]", "Enable source map/specify source map options.", parse_source_map());
67
65
  program.option("--timings", "Display operations run time on STDERR.");
68
66
  program.option("--toplevel", "Compress and/or mangle variables in toplevel scope.");
@@ -169,16 +167,7 @@ if (program.verbose) {
169
167
  } else if (program.warn) {
170
168
  options.warnings = true;
171
169
  }
172
- if (program.self) {
173
- if (program.args.length) {
174
- print_error("WARN: Ignoring input files since --self was passed");
175
- }
176
- if (!options.wrap) options.wrap = "Terser";
177
- simple_glob(UglifyJS.FILES).forEach(function(name) {
178
- files[convert_path(name)] = read_file(name);
179
- });
180
- run();
181
- } else if (program.args.length) {
170
+ if (program.args.length) {
182
171
  simple_glob(program.args).forEach(function(name) {
183
172
  files[convert_path(name)] = read_file(name);
184
173
  });
@@ -328,7 +317,7 @@ function simple_glob(glob) {
328
317
  if (Array.isArray(glob)) {
329
318
  return [].concat.apply([], glob.map(simple_glob));
330
319
  }
331
- if (glob.match(/\*|\?/)) {
320
+ if (glob && glob.match(/\*|\?/)) {
332
321
  var dir = path.dirname(glob);
333
322
  try {
334
323
  var entries = fs.readdirSync(dir);
@@ -455,3 +444,38 @@ function print(txt) {
455
444
  process.stdout.write(txt);
456
445
  process.stdout.write("\n");
457
446
  }
447
+
448
+ function describe_ast() {
449
+ var out = UglifyJS.OutputStream({ beautify: true });
450
+ function doitem(ctor) {
451
+ out.print("AST_" + ctor.TYPE);
452
+ var props = ctor.SELF_PROPS.filter(function(prop){
453
+ return !/^\$/.test(prop);
454
+ });
455
+ if (props.length > 0) {
456
+ out.space();
457
+ out.with_parens(function(){
458
+ props.forEach(function(prop, i){
459
+ if (i) out.space();
460
+ out.print(prop);
461
+ });
462
+ });
463
+ }
464
+ if (ctor.documentation) {
465
+ out.space();
466
+ out.print_string(ctor.documentation);
467
+ }
468
+ if (ctor.SUBCLASSES.length > 0) {
469
+ out.space();
470
+ out.with_block(function(){
471
+ ctor.SUBCLASSES.forEach(function(ctor, i){
472
+ out.indent();
473
+ doitem(ctor);
474
+ out.newline();
475
+ });
476
+ });
477
+ }
478
+ };
479
+ doitem(UglifyJS.AST_Node);
480
+ return out + "\n";
481
+ }
@@ -763,7 +763,7 @@
763
763
  },
764
764
  _walk: function(visitor) {
765
765
  return visitor._visit(this, function() {
766
- this.argname._walk(visitor);
766
+ if (this.argname) this.argname._walk(visitor);
767
767
  walk_body(this, visitor);
768
768
  });
769
769
  }
@@ -1516,7 +1516,7 @@
1516
1516
  var valid = parse_js_number(num);
1517
1517
  if (!isNaN(valid)) return token("num", valid); else parse_error("Invalid syntax: " + num);
1518
1518
  }
1519
- function read_escaped_char(in_string) {
1519
+ function read_escaped_char(in_string, template_string) {
1520
1520
  var ch = next(true, in_string);
1521
1521
  switch (ch.charCodeAt(0)) {
1522
1522
  case 110:
@@ -1550,7 +1550,7 @@
1550
1550
  next(true);
1551
1551
  return from_char_code(result);
1552
1552
  }
1553
- return String.fromCharCode(hex_bytes(4));
1553
+ return String.fromCharCode(hex_bytes(4, template_string));
1554
1554
 
1555
1555
  case 10:
1556
1556
  return "";
@@ -1574,9 +1574,10 @@
1574
1574
  if (ch.length > 0 && next_token.has_directive("use strict")) parse_error("Legacy octal escape sequences are not allowed in strict mode");
1575
1575
  return String.fromCharCode(parseInt(ch, 8));
1576
1576
  }
1577
- function hex_bytes(n) {
1577
+ function hex_bytes(n, abrupt_ending) {
1578
1578
  var num = 0;
1579
1579
  for (;n > 0; --n) {
1580
+ if (abrupt_ending && isNaN(parseInt(peek(), 16))) return num || "";
1580
1581
  var digit = parseInt(next(true), 16);
1581
1582
  if (isNaN(digit)) parse_error("Invalid hex-character pattern in string");
1582
1583
  num = num << 4 | digit;
@@ -1614,7 +1615,7 @@
1614
1615
  raw += ch;
1615
1616
  if ("\\" == ch) {
1616
1617
  var tmp = S.pos;
1617
- ch = read_escaped_char(true);
1618
+ ch = read_escaped_char(true, true);
1618
1619
  raw += S.text.substr(tmp, S.pos - tmp);
1619
1620
  }
1620
1621
  content += ch;
@@ -2640,9 +2641,11 @@
2640
2641
  if (is("keyword", "catch")) {
2641
2642
  var start = S.token;
2642
2643
  next();
2643
- expect("(");
2644
- var name = parameter(void 0, AST_SymbolCatch);
2645
- expect(")");
2644
+ if (is("punc", "{")) var name = null; else {
2645
+ expect("(");
2646
+ var name = parameter(void 0, AST_SymbolCatch);
2647
+ expect(")");
2648
+ }
2646
2649
  bcatch = new AST_Catch({
2647
2650
  start: start,
2648
2651
  argname: name,
@@ -3662,7 +3665,7 @@
3662
3665
  if (self.bfinally) self.bfinally = self.bfinally.transform(tw);
3663
3666
  });
3664
3667
  _(AST_Catch, function(self, tw) {
3665
- self.argname = self.argname.transform(tw);
3668
+ if (self.argname) self.argname = self.argname.transform(tw);
3666
3669
  self.body = do_list(self.body, tw);
3667
3670
  });
3668
3671
  _(AST_Definitions, function(self, tw) {
@@ -3770,7 +3773,7 @@
3770
3773
  SymbolDef.prototype = {
3771
3774
  unmangleable: function(options) {
3772
3775
  if (!options) options = {};
3773
- return this.global && !options.toplevel || this.export || this.undeclared || !options.eval && this.scope.pinned() || options.keep_fnames && (this.orig[0] instanceof AST_SymbolLambda || this.orig[0] instanceof AST_SymbolDefun) || this.orig[0] instanceof AST_SymbolMethod || options.keep_classnames && (this.orig[0] instanceof AST_SymbolClass || this.orig[0] instanceof AST_SymbolDefClass);
3776
+ return this.global && !options.toplevel || this.export || this.undeclared || !options.eval && this.scope.pinned() || (options.keep_fnames instanceof RegExp && options.keep_fnames.test(this.orig[0].name) || true === options.keep_fnames) && (this.orig[0] instanceof AST_SymbolLambda || this.orig[0] instanceof AST_SymbolDefun) || this.orig[0] instanceof AST_SymbolMethod || (options.keep_classnames instanceof RegExp && options.keep_classnames.test(this.orig[0].name) || true === options.keep_classnames) && (this.orig[0] instanceof AST_SymbolClass || this.orig[0] instanceof AST_SymbolDefClass);
3774
3777
  },
3775
3778
  mangle: function(options) {
3776
3779
  var cache = options.cache && options.cache.props;
@@ -5208,10 +5211,12 @@
5208
5211
  });
5209
5212
  DEFPRINT(AST_Catch, function(self, output) {
5210
5213
  output.print("catch");
5211
- output.space();
5212
- output.with_parens(function() {
5213
- self.argname.print(output);
5214
- });
5214
+ if (self.argname) {
5215
+ output.space();
5216
+ output.with_parens(function() {
5217
+ self.argname.print(output);
5218
+ });
5219
+ }
5215
5220
  output.space();
5216
5221
  print_braced(self, output);
5217
5222
  });
@@ -5595,6 +5600,7 @@
5595
5600
  arguments: false,
5596
5601
  arrows: !false_by_default,
5597
5602
  booleans: !false_by_default,
5603
+ booleans_as_integers: false,
5598
5604
  collapse_vars: !false_by_default,
5599
5605
  comparisons: !false_by_default,
5600
5606
  computed_props: !false_by_default,
@@ -6272,7 +6278,7 @@
6272
6278
  var scope, i = 0;
6273
6279
  while (scope = compressor.parent(i++)) {
6274
6280
  if (scope instanceof AST_Scope) break;
6275
- if (scope instanceof AST_Catch) {
6281
+ if (scope instanceof AST_Catch && scope.argname) {
6276
6282
  scope = scope.argname.definition().scope;
6277
6283
  break;
6278
6284
  }
@@ -9236,10 +9242,6 @@
9236
9242
  });
9237
9243
  }
9238
9244
  break;
9239
-
9240
- case "Symbol":
9241
- self.args = [];
9242
- return self;
9243
9245
  } else if (exp instanceof AST_Dot) switch (exp.property) {
9244
9246
  case "toString":
9245
9247
  if (0 == self.args.length && !exp.expression.may_throw_on_access(compressor)) return make_node(AST_Binary, self, {
@@ -9407,7 +9409,8 @@
9407
9409
  if (can_inline && stat instanceof AST_Return && is_regular_func) {
9408
9410
  var value = stat.value;
9409
9411
  if (!value || value.is_constant_expression()) {
9410
- var args = self.args.concat(value || make_node(AST_Undefined, self));
9412
+ if (value) value = value.clone(true); else value = make_node(AST_Undefined, self);
9413
+ var args = self.args.concat(value);
9411
9414
  return make_sequence(self, args).optimize(compressor);
9412
9415
  }
9413
9416
  }
@@ -9499,7 +9502,9 @@
9499
9502
  if (scope.is_block_scope() && !(compressor.parent(level - 1) instanceof AST_Scope)) if (scope.block_scope) scope.block_scope.variables.each(function(variable) {
9500
9503
  block_scoped[variable.name] = true;
9501
9504
  });
9502
- if (scope instanceof AST_Catch) block_scoped[scope.argname.name] = true; else if (scope instanceof AST_IterationStatement) in_loop = []; else if (scope instanceof AST_SymbolRef) if (scope.fixed_value() instanceof AST_Scope) return false;
9505
+ if (scope instanceof AST_Catch) {
9506
+ if (scope.argname) block_scoped[scope.argname.name] = true;
9507
+ } else if (scope instanceof AST_IterationStatement) in_loop = []; else if (scope instanceof AST_SymbolRef) if (scope.fixed_value() instanceof AST_Scope) return false;
9503
9508
  } while (!(scope instanceof AST_Scope) || scope instanceof AST_Arrow);
9504
9509
  var safe_to_inject = !(scope instanceof AST_Toplevel) || compressor.toplevel.vars;
9505
9510
  var inline = compressor.option("inline");
@@ -10369,8 +10374,14 @@
10369
10374
  if (compressor.in_boolean_context()) return make_node(AST_Number, self, {
10370
10375
  value: +self.value
10371
10376
  });
10377
+ var p = compressor.parent();
10378
+ if (compressor.option("booleans_as_integers")) {
10379
+ if (p instanceof AST_Binary && ("===" == p.operator || "!==" == p.operator)) p.operator = p.operator.replace(/=$/, "");
10380
+ return make_node(AST_Number, self, {
10381
+ value: +self.value
10382
+ });
10383
+ }
10372
10384
  if (compressor.option("booleans")) {
10373
- var p = compressor.parent();
10374
10385
  if (p instanceof AST_Binary && ("==" == p.operator || "!=" == p.operator)) {
10375
10386
  compressor.warn("Non-strict equality against boolean: {operator} {value} [{file}:{line},{col}]", {
10376
10387
  operator: p.operator,
@@ -11990,7 +12001,8 @@
11990
12001
  exports["minify"] = minify;
11991
12002
  exports["parse"] = parse;
11992
12003
  exports["push_uniq"] = push_uniq;
12004
+ exports["OutputStream"] = OutputStream;
11993
12005
  exports["TreeTransformer"] = TreeTransformer;
11994
12006
  exports["TreeWalker"] = TreeWalker;
11995
12007
  })("undefined" != typeof module ? module.exports : Terser = {});
11996
- //# sourceMappingURL=browser.bundle.js.map
12008
+ //# sourceMappingURL=bundle.js.map