terser 3.14.1 → 4.0.0

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/CHANGELOG.md ADDED
@@ -0,0 +1,40 @@
1
+ # Changelog
2
+
3
+ ## v4.0.0
4
+
5
+ - **breaking change**: The `variables` property of all scopes has become a standard JavaScript `Map` as opposed to the old bespoke `Dictionary` object.
6
+ - Typescript definitions were fixed
7
+ - `terser --help` was fixed
8
+ - The public interface was cleaned up
9
+ - Fixed optimisation of `Array` and `new Array`
10
+ - Added the `keep_quoted=strict` mode to mangle_props, which behaves more like Google Closure Compiler by mangling all unquoted property names, instead of reserving quoted property names automatically.
11
+ - Fixed parent functions' parameters being shadowed in some cases
12
+ - Allowed Terser to run in a situation where there are custom functions attached to Object.prototype
13
+ - And more bug fixes, optimisations and internal changes
14
+
15
+ ## v3.17.0
16
+
17
+ - More DOM properties added to --mangle-properties's DOM property list
18
+ - Closed issue where if 2 functions had the same argument name, Terser would not inline them together properly
19
+ - Fixed issue with `hasOwnProperty.call`
20
+ - You can now list files to minify in a Terser config file
21
+ - Started replacing `new Array(<number>)` with an array literal
22
+ - Started using ES6 capabilities like `Set` and the `includes` method for strings and arrays
23
+
24
+ ## v3.16.1
25
+
26
+ - Fixed issue where Terser being imported with `import` would cause it not to work due to the `__esModule` property. (PR #254 was submitted, which was nice, but since it wasn't a pure commonJS approach I decided to go with my own solution)
27
+
28
+ ## v3.16.0
29
+
30
+ - No longer leaves names like Array or Object or window as a SimpleStatement (statement which is just a single expression).
31
+ - Add support for sections sourcemaps (IndexedSourceMapConsumer)
32
+ - Drops node.js v4 and starts using commonJS
33
+ - Is now built with rollup
34
+
35
+ ## v3.15.0
36
+
37
+ - Inlined spread syntax (`[...[1, 2, 3], 4, 5] => [1, 2, 3, 4, 5]`) in arrays and objects.
38
+ - Fixed typo in compressor warning
39
+ - Fixed inline source map input bug
40
+ - Fixed parsing of template literals with unnecessary escapes (Like `\\a`)
package/PATRONS.md ADDED
@@ -0,0 +1,11 @@
1
+ # Our patrons
2
+
3
+ These are the first-tier patrons from [Patreon](https://www.patreon.com/fabiosantoscode). My appreciation goes to everyone on this list for supporting the project!
4
+
5
+ * 38elements
6
+ * Alan Orozco
7
+ * CKEditor
8
+ * Mariusz Nowak
9
+ * Philippe Léger
10
+ * Piotrek Koszuliński
11
+ * Viktor Hubert
package/README.md CHANGED
@@ -5,13 +5,17 @@ terser
5
5
 
6
6
  A JavaScript parser and mangler/compressor toolkit for ES6+.
7
7
 
8
- *note*: You can support this project on patreon: <a target="_blank" rel="nofollow" href="https://www.patreon.com/terser_jscomp_maintainer"><img src="https://c5.patreon.com/external/logo/become_a_patron_button@2x.png" alt="patron" width="100px" height="auto"></a>. Check out PATRONS.md for our first-tier patrons.
8
+ *note*: You can support this project on patreon: <a target="_blank" rel="nofollow" href="https://www.patreon.com/fabiosantoscode"><img src="https://c5.patreon.com/external/logo/become_a_patron_button@2x.png" alt="patron" width="100px" height="auto"></a>. Check out [PATRONS.md](https://github.com/terser-js/terser/blob/master/PATRONS.md) for our first-tier patrons.
9
9
 
10
10
  Terser recommends you use RollupJS to bundle your modules, as that produces smaller code overall.
11
11
 
12
12
  *Beautification* has been undocumented and is *being removed* from terser, we recommend you use [prettier](https://npmjs.com/package/prettier).
13
13
 
14
- [![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)
14
+ [![Build Status](https://travis-ci.org/terser-js/terser.svg?branch=master)](https://travis-ci.org/terser-js/terser)
15
+
16
+ Find the changelog in [CHANGELOG.md](https://github.com/terser-js/terser/blob/master/CHANGELOG.md)
17
+
18
+ A JavaScript parser, mangler/compressor and beautifier toolkit for ES6+.
15
19
 
16
20
 
17
21
  Why choose terser?
@@ -19,7 +23,7 @@ Why choose terser?
19
23
 
20
24
  `uglify-es` is [no longer maintained](https://github.com/mishoo/UglifyJS2/issues/3156#issuecomment-392943058) and `uglify-js` does not support ES6+.
21
25
 
22
- **`terser`** is a fork of `uglify-es` that retains API and CLI compatibility
26
+ **`terser`** is a fork of `uglify-es` that mostly retains API and CLI compatibility
23
27
  with `uglify-es` and `uglify-js@3`.
24
28
 
25
29
  Install
@@ -82,9 +86,13 @@ a double dash to prevent input files being used as option arguments:
82
86
  `debug` Add debug prefix and suffix.
83
87
  `domprops` Mangle property names that overlaps
84
88
  with DOM properties.
85
- `keep_quoted` Only mangle unquoted properties.
89
+ `keep_quoted` Only mangle unquoted properties, quoted
90
+ properties are automatically reserved.
91
+ `strict` disables quoted properties
92
+ being automatically reserved.
86
93
  `regex` Only mangle matched property names.
87
94
  `reserved` List of names that should not be mangled.
95
+ -b, --beautify [options] Specify output options:
88
96
  `preamble` Preamble to prepend to the output. You
89
97
  can use this to insert a comment, for
90
98
  example for licensing information.
@@ -237,11 +245,28 @@ to prevent the `require`, `exports` and `$` names from being changed.
237
245
 
238
246
  ### CLI mangling property names (`--mangle-props`)
239
247
 
240
- **Note:** THIS *MIGHT* BREAK YOUR CODE. Mangling property names
241
- is a separate step, different from variable name mangling. Pass
242
- `--mangle-props` to enable it. It will mangle all properties in the
248
+ **Note:** THIS **WILL** BREAK YOUR CODE. A good rule of thumb is not to use this unless you know exactly what you're doing and how this works and read this section until the end.
249
+
250
+ Mangling property names is a separate step, different from variable name mangling. Pass
251
+ `--mangle-props` to enable it. The least dangerous
252
+ way to use this is to use the `regex` option like so:
253
+
254
+ ```
255
+ terser example.js -c -m --mangle-props regex=/_$/
256
+ ```
257
+
258
+ This will mangle all properties that start with an
259
+ underscore. So you can use it to mangle internal methods.
260
+
261
+ By default, it will mangle all properties in the
243
262
  input code with the exception of built in DOM properties and properties
244
- in core JavaScript classes. For example:
263
+ in core JavaScript classes, which is what will break your code if you don't:
264
+
265
+ 1. Control all the code you're mangling
266
+ 2. Avoid using a module bundler, as they usually will call Terser on each file individually, making it impossible to pass mangled objects between modules.
267
+ 3. Avoid calling functions like `defineProperty` or `hasOwnProperty`, because they refer to object properties using strings and will break your code if you don't know what you are doing.
268
+
269
+ An example:
245
270
 
246
271
  ```javascript
247
272
  // example.js
@@ -256,21 +281,21 @@ x.bar_ = 2;
256
281
  x["baz_"] = 3;
257
282
  console.log(x.calc());
258
283
  ```
259
- Mangle all properties (except for JavaScript `builtins`):
284
+ Mangle all properties (except for JavaScript `builtins`) (**very** unsafe):
260
285
  ```bash
261
286
  $ terser example.js -c -m --mangle-props
262
287
  ```
263
288
  ```javascript
264
289
  var x={o:0,_:1,l:function(){return this._+this.o}};x.t=2,x.o=3,console.log(x.l());
265
290
  ```
266
- Mangle all properties except for `reserved` properties:
291
+ Mangle all properties except for `reserved` properties (still very unsafe):
267
292
  ```bash
268
293
  $ terser example.js -c -m --mangle-props reserved=[foo_,bar_]
269
294
  ```
270
295
  ```javascript
271
296
  var x={o:0,foo_:1,_:function(){return this.foo_+this.o}};x.bar_=2,x.o=3,console.log(x._());
272
297
  ```
273
- Mangle all properties matching a `regex`:
298
+ Mangle all properties matching a `regex` (not as unsafe but still unsafe):
274
299
  ```bash
275
300
  $ terser example.js -c -m --mangle-props regex=/_$/
276
301
  ```
@@ -367,6 +392,11 @@ like this:
367
392
  ```javascript
368
393
  var Terser = require("terser");
369
394
  ```
395
+ Browser loading is also supported:
396
+ ```html
397
+ <script src="node_modules/source-map/dist/source-map.min.js"></script>
398
+ <script src="dist/bundle.min.js"></script>
399
+ ```
370
400
 
371
401
  There is a single high level function, **`minify(code, options)`**,
372
402
  which will perform all minification [phases](#minify-options) in a configurable
@@ -459,6 +489,7 @@ var options = {
459
489
  passes: 2
460
490
  },
461
491
  output: {
492
+ beautify: false,
462
493
  preamble: "/* minified */"
463
494
  }
464
495
  };
@@ -900,28 +931,37 @@ Terser.minify(code, { mangle: { toplevel: true } }).code;
900
931
 
901
932
  ### Mangle properties options
902
933
 
903
- - `builtins` (default: `false`) -- Use `true` to allow the mangling of builtin
934
+ - `builtins` (default: `false`) Use `true` to allow the mangling of builtin
904
935
  DOM properties. Not recommended to override this setting.
905
936
 
906
- - `debug` (default: `false`) -— Mangle names with the original name still present.
937
+ - `debug` (default: `false`) Mangle names with the original name still present.
907
938
  Pass an empty string `""` to enable, or a non-empty string to set the debug suffix.
908
939
 
909
- - `keep_quoted` (default: `false`) -— Only mangle unquoted property names.
940
+ - `keep_quoted` (default: `false`) Only mangle unquoted property names.
941
+ - `true` -- Quoted property names are automatically reserved and any unquoted
942
+ property names will not be mangled.
943
+ - `"strict"` -- Advanced, all unquoted property names are mangled unless
944
+ explicitly reserved.
910
945
 
911
- - `regex` (default: `null`) -— Pass a RegExp literal to only mangle property
912
- names matching the regular expression.
946
+ - `regex` (default: `null`) Pass a [RegExp literal or pattern string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp) to only mangle property matching the regular expression.
913
947
 
914
- - `reserved` (default: `[]`) -- Do not mangle property names listed in the
948
+ - `reserved` (default: `[]`) Do not mangle property names listed in the
915
949
  `reserved` array.
916
950
 
917
951
  ## Output options
918
952
 
919
- The code generator tries to output shortest code possible. Optionally you
953
+ The code generator tries to output shortest code possible by default. In
954
+ case you want beautified output, pass `--beautify` (`-b`). Optionally you
920
955
  can pass additional arguments that control the code output:
921
956
 
922
957
  - `ascii_only` (default `false`) -- escape Unicode characters in strings and
923
958
  regexps (affects directives with non-ascii characters becoming invalid)
924
959
 
960
+ - `beautify` (default `true`) -- whether to actually beautify the output.
961
+ Passing `-b` will set this to true, but you might need to pass `-b` even
962
+ when you want to generate minified code, in order to specify additional
963
+ arguments, so you can use `-b beautify=false` to override it.
964
+
925
965
  - `braces` (default `false`) -- always insert braces in `if`, `for`,
926
966
  `do`, `while` or `with` statements, even if their body is a single
927
967
  statement.
@@ -932,7 +972,8 @@ can pass additional arguments that control the code output:
932
972
 
933
973
  - `ecma` (default `5`) -- set output printing mode. Set `ecma` to `6` or
934
974
  greater to emit shorthand object properties - i.e.: `{a}` instead of `{a: a}`.
935
- Non-compatible features in the abstract syntax tree will still
975
+ The `ecma` option will only change the output in direct control of the
976
+ beautifier. Non-compatible features in the abstract syntax tree will still
936
977
  be output as is. For example: an `ecma` setting of `5` will **not** convert
937
978
  ES6+ code to ES5.
938
979
 
@@ -1263,8 +1304,9 @@ In the terser CLI we use [source-map-support](https://npmjs.com/source-map-suppo
1263
1304
 
1264
1305
  # README.md Patrons:
1265
1306
 
1266
- *note*: You can support this project on patreon: <a target="_blank" rel="nofollow" href="https://www.patreon.com/terser_jscomp_maintainer"><img src="https://c5.patreon.com/external/logo/become_a_patron_button@2x.png" alt="patron" width="100px" height="auto"></a>. Check out PATRONS.md for our first-tier patrons.
1267
-
1307
+ *note*: You can support this project on patreon: <a target="_blank" rel="nofollow" href="https://www.patreon.com/fabiosantoscode"><img src="https://c5.patreon.com/external/logo/become_a_patron_button@2x.png" alt="patron" width="100px" height="auto"></a>. Check out [PATRONS.md](https://github.com/terser-js/terser/blob/master/PATRONS.md) for our first-tier patrons.
1268
1308
 
1269
- * CKEditor ![CKEditor](https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/15452278/f8548dcf48d740619071e8d614459280/1?token-time=2145916800&token-hash=SIQ54PhIPHv3M7CVz9LxS8_8v4sOw4H304HaXsXj8MM%3D)
1309
+ These are the second-tier patrons. Great thanks for your support!
1270
1310
 
1311
+ * CKEditor ![](https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/15452278/f8548dcf48d740619071e8d614459280/1?token-time=2145916800&token-hash=SIQ54PhIPHv3M7CVz9LxS8_8v4sOw4H304HaXsXj8MM%3D)
1312
+ * 38elements ![](https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/12501844/88e7fc5dd62d45c6a5626533bbd48cfb/1?token-time=2145916800&token-hash=c3AsQ5T0IQWic0zKxFHu-bGGQJkXQFvafvJ4bPerFR4%3D)
package/bin/uglifyjs CHANGED
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  // -*- js -*-
3
+ /* eslint-env node */
3
4
 
4
5
  "use strict";
5
6
 
@@ -10,15 +11,13 @@ var info = require("../package.json");
10
11
  var path = require("path");
11
12
  var program = require("commander");
12
13
 
13
- var bundle_path = __dirname + "/../dist/bundle.js";
14
- if (!process.env.TERSER_NO_BUNDLE && fs.existsSync(bundle_path)) {
15
- var UglifyJS = require(bundle_path)
16
- try {
17
- require("source-map-support").install();
18
- } catch (err) {}
19
- } else {
20
- var UglifyJS = require("../tools/node.js");
21
- }
14
+ var bundle_path = __dirname + (process.env.TERSER_NO_BUNDLE ?
15
+ "/../dist/bundle.js" :
16
+ "/../dist/bundle.min.js");
17
+ var UglifyJS = require(bundle_path);
18
+ try {
19
+ require("source-map-support").install();
20
+ } catch (err) {}
22
21
 
23
22
  var skip_keys = [ "cname", "inlined", "parent_scope", "scope", "uses_eval", "uses_with" ];
24
23
  var files = {};
@@ -29,12 +28,12 @@ var options = {
29
28
  program.version(info.name + " " + info.version);
30
29
  program.parseArgv = program.parse;
31
30
  program.parse = undefined;
32
- if (process.argv.indexOf("ast") >= 0) program.helpInformation = describe_ast;
33
- else if (process.argv.indexOf("options") >= 0) program.helpInformation = function() {
31
+ if (process.argv.includes("ast")) program.helpInformation = describe_ast;
32
+ else if (process.argv.includes("options")) program.helpInformation = function() {
34
33
  var text = [];
35
34
  var options = UglifyJS.default_options();
36
35
  for (var option in options) {
37
- text.push("--" + (option == "output" ? "beautify" : option == "sourceMap" ? "source-map" : option) + " options:");
36
+ text.push("--" + (option === "output" ? "beautify" : option === "sourceMap" ? "source-map" : option) + " options:");
38
37
  text.push(format_object(options[option]));
39
38
  text.push("");
40
39
  }
@@ -162,8 +161,18 @@ if (program.verbose) {
162
161
  } else if (program.warn) {
163
162
  options.warnings = true;
164
163
  }
165
- if (program.args.length) {
166
- simple_glob(program.args).forEach(function(name) {
164
+
165
+ let filesList;
166
+ if (options.files && options.files.length) {
167
+ filesList = options.files;
168
+
169
+ delete options.files;
170
+ } else if (program.args.length) {
171
+ filesList = program.args;
172
+ }
173
+
174
+ if (filesList) {
175
+ simple_glob(filesList).forEach(function(name) {
167
176
  files[convert_path(name)] = read_file(name);
168
177
  });
169
178
  run();
@@ -252,11 +261,11 @@ function run() {
252
261
  case "variables":
253
262
  case "functions":
254
263
  case "globals":
255
- return value.size() ? value.map(symdef) : undefined;
264
+ return value.size ? collect_from_map(value, symdef) : undefined;
256
265
  }
257
266
  if (skip_key(key)) return;
258
267
  if (value instanceof UglifyJS.AST_Token) return;
259
- if (value instanceof UglifyJS.Dictionary) return;
268
+ if (value instanceof Map) return;
260
269
  if (value instanceof UglifyJS.AST_Node) {
261
270
  var result = {
262
271
  _class: "AST_" + value.TYPE
@@ -299,7 +308,7 @@ function run() {
299
308
  }
300
309
 
301
310
  function fatal(message) {
302
- if (message instanceof Error) message = message.stack.replace(/^\S*?Error:/, "ERROR:")
311
+ if (message instanceof Error) message = message.stack.replace(/^\S*?Error:/, "ERROR:");
303
312
  print_error(message);
304
313
  process.exit(1);
305
314
  }
@@ -312,7 +321,7 @@ function simple_glob(glob) {
312
321
  if (Array.isArray(glob)) {
313
322
  return [].concat.apply([], glob.map(simple_glob));
314
323
  }
315
- if (glob && glob.match(/\*|\?/)) {
324
+ if (glob && glob.match(/[*?]/)) {
316
325
  var dir = path.dirname(glob);
317
326
  try {
318
327
  var entries = fs.readdirSync(dir);
@@ -392,7 +401,7 @@ function parse_js(flag) {
392
401
  }
393
402
  }
394
403
  return options;
395
- }
404
+ };
396
405
  }
397
406
 
398
407
  function parse_source_map() {
@@ -401,15 +410,14 @@ function parse_source_map() {
401
410
  var hasContent = options && "content" in options;
402
411
  var settings = parse(value, options);
403
412
  if (!hasContent && settings.content && settings.content != "inline") {
404
- print_error("INFO: Using input source map: " + settings.content);
405
413
  settings.content = read_file(settings.content, settings.content);
406
414
  }
407
415
  return settings;
408
- }
416
+ };
409
417
  }
410
418
 
411
419
  function skip_key(key) {
412
- return skip_keys.indexOf(key) >= 0;
420
+ return skip_keys.includes(key);
413
421
  }
414
422
 
415
423
  function symdef(def) {
@@ -418,6 +426,14 @@ function symdef(def) {
418
426
  return ret;
419
427
  }
420
428
 
429
+ function collect_from_map(map, callback) {
430
+ var result = [];
431
+ map.forEach(function (def) {
432
+ result.push(callback(def));
433
+ });
434
+ return result;
435
+ }
436
+
421
437
  function format_object(obj) {
422
438
  var lines = [];
423
439
  var padding = "";
@@ -444,13 +460,13 @@ function describe_ast() {
444
460
  var out = UglifyJS.OutputStream({ beautify: true });
445
461
  function doitem(ctor) {
446
462
  out.print("AST_" + ctor.TYPE);
447
- var props = ctor.SELF_PROPS.filter(function(prop){
463
+ var props = ctor.SELF_PROPS.filter(function(prop) {
448
464
  return !/^\$/.test(prop);
449
465
  });
450
466
  if (props.length > 0) {
451
467
  out.space();
452
- out.with_parens(function(){
453
- props.forEach(function(prop, i){
468
+ out.with_parens(function() {
469
+ props.forEach(function(prop, i) {
454
470
  if (i) out.space();
455
471
  out.print(prop);
456
472
  });
@@ -462,15 +478,15 @@ function describe_ast() {
462
478
  }
463
479
  if (ctor.SUBCLASSES.length > 0) {
464
480
  out.space();
465
- out.with_block(function(){
466
- ctor.SUBCLASSES.forEach(function(ctor, i){
481
+ out.with_block(function() {
482
+ ctor.SUBCLASSES.forEach(function(ctor, i) {
467
483
  out.indent();
468
484
  doitem(ctor);
469
485
  out.newline();
470
486
  });
471
487
  });
472
488
  }
473
- };
489
+ }
474
490
  doitem(UglifyJS.AST_Node);
475
491
  return out + "\n";
476
492
  }
@@ -1,3 +1,4 @@
1
1
  #!/usr/bin/env node
2
- process.env.TERSER_NO_BUNDLE = '1'
3
- require('./uglifyjs')
2
+ /* eslint-env node */
3
+ process.env.TERSER_NO_BUNDLE = "1";
4
+ require("./uglifyjs");