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 +40 -0
- package/PATRONS.md +11 -0
- package/README.md +64 -22
- package/bin/uglifyjs +44 -28
- package/bin/uglifyjsnobundle +3 -2
- package/dist/bundle.js +21797 -45
- package/dist/bundle.js.map +1 -1
- package/dist/bundle.min.js +1 -0
- package/dist/bundle.min.js.map +1 -0
- package/package.json +34 -22
- package/tools/domprops.js +5 -1
- package/tools/node.js +11 -47
- package/tools/terser.d.ts +6 -16
- package/lib/ast.js +0 -1260
- package/lib/compress.js +0 -6801
- package/lib/minify.js +0 -260
- package/lib/mozilla-ast.js +0 -1087
- package/lib/output.js +0 -1939
- package/lib/parse.js +0 -2986
- package/lib/propmangle.js +0 -271
- package/lib/scope.js +0 -723
- package/lib/sourcemap.js +0 -97
- package/lib/transform.js +0 -275
- package/lib/utils.js +0 -350
- package/tools/exports.js +0 -14
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/
|
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
|
-
[](https://travis-ci.org/terser-js/terser)
|
14
|
+
[](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
|
241
|
-
|
242
|
-
|
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
|
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`)
|
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`)
|
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`)
|
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`)
|
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: `[]`)
|
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
|
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
|
-
|
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/
|
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
|
-
|
1309
|
+
These are the second-tier patrons. Great thanks for your support!
|
1270
1310
|
|
1311
|
+
* CKEditor 
|
1312
|
+
* 38elements 
|
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 +
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
}
|
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.
|
33
|
-
else if (process.argv.
|
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
|
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
|
-
|
166
|
-
|
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
|
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
|
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.
|
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
|
}
|
package/bin/uglifyjsnobundle
CHANGED