terser 5.6.1 → 5.8.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.
- package/CHANGELOG.md +39 -0
- package/README.md +46 -21
- package/dist/bundle.min.js +4718 -3740
- package/lib/ast.js +13 -7
- package/lib/cli.js +0 -2
- package/lib/compress/common.js +296 -0
- package/lib/compress/compressor-flags.js +63 -0
- package/lib/compress/drop-side-effect-free.js +353 -0
- package/lib/compress/evaluate.js +458 -0
- package/lib/compress/index.js +483 -3608
- package/lib/compress/inference.js +934 -0
- package/lib/compress/native-objects.js +183 -0
- package/lib/compress/reduce-vars.js +675 -0
- package/lib/compress/tighten-body.js +1461 -0
- package/lib/equivalent-to.js +5 -0
- package/lib/minify.js +28 -11
- package/lib/output.js +20 -7
- package/lib/parse.js +76 -82
- package/lib/propmangle.js +54 -31
- package/lib/scope.js +49 -24
- package/lib/transform.js +2 -2
- package/lib/utils/index.js +3 -5
- package/package.json +13 -12
- package/tools/terser.d.ts +37 -0
package/lib/scope.js
CHANGED
@@ -107,7 +107,7 @@ import {
|
|
107
107
|
walk
|
108
108
|
} from "./ast.js";
|
109
109
|
import {
|
110
|
-
|
110
|
+
ALL_RESERVED_WORDS,
|
111
111
|
js_error,
|
112
112
|
} from "./parse.js";
|
113
113
|
|
@@ -299,7 +299,14 @@ AST_Scope.DEFMETHOD("figure_out_scope", function(options, { parent_scope = null,
|
|
299
299
|
// scope when we encounter the AST_Defun node (which is
|
300
300
|
// instanceof AST_Scope) but we get to the symbol a bit
|
301
301
|
// later.
|
302
|
-
|
302
|
+
const closest_scope = defun.parent_scope;
|
303
|
+
|
304
|
+
// In strict mode, function definitions are block-scoped
|
305
|
+
node.scope = tw.directives["use strict"]
|
306
|
+
? closest_scope
|
307
|
+
: closest_scope.get_defun_scope();
|
308
|
+
|
309
|
+
mark_export(node.scope.def_function(node, defun), 1);
|
303
310
|
} else if (node instanceof AST_SymbolClass) {
|
304
311
|
mark_export(defun.def_variable(node, defun), 1);
|
305
312
|
} else if (node instanceof AST_SymbolImport) {
|
@@ -478,7 +485,6 @@ AST_Toplevel.DEFMETHOD("def_global", function(node) {
|
|
478
485
|
|
479
486
|
AST_Scope.DEFMETHOD("init_scope_vars", function(parent_scope) {
|
480
487
|
this.variables = new Map(); // map name to AST_SymbolVar (variables defined in this scope; includes functions)
|
481
|
-
this.functions = new Map(); // map name to AST_SymbolDefun (functions defined in this scope)
|
482
488
|
this.uses_with = false; // will be set to true if this or some nested scope uses the `with` statement
|
483
489
|
this.uses_eval = false; // will be set to true if this or nested scope uses the global `eval`
|
484
490
|
this.parent_scope = parent_scope; // the parent scope
|
@@ -641,7 +647,6 @@ AST_Scope.DEFMETHOD("find_variable", function(name) {
|
|
641
647
|
AST_Scope.DEFMETHOD("def_function", function(symbol, init) {
|
642
648
|
var def = this.def_variable(symbol, init);
|
643
649
|
if (!def.init || def.init instanceof AST_Defun) def.init = init;
|
644
|
-
this.functions.set(symbol.name, def);
|
645
650
|
return def;
|
646
651
|
});
|
647
652
|
|
@@ -662,9 +667,10 @@ AST_Scope.DEFMETHOD("def_variable", function(symbol, init) {
|
|
662
667
|
|
663
668
|
function next_mangled(scope, options) {
|
664
669
|
var ext = scope.enclosed;
|
670
|
+
var nth_identifier = options.nth_identifier;
|
665
671
|
out: while (true) {
|
666
|
-
var m =
|
667
|
-
if (
|
672
|
+
var m = nth_identifier.get(++scope.cname);
|
673
|
+
if (ALL_RESERVED_WORDS.has(m)) continue; // skip over "do"
|
668
674
|
|
669
675
|
// https://github.com/mishoo/UglifyJS2/issues/242 -- do not
|
670
676
|
// shadow a name reserved from mangling.
|
@@ -739,6 +745,7 @@ AST_Symbol.DEFMETHOD("global", function() {
|
|
739
745
|
AST_Toplevel.DEFMETHOD("_default_mangler_options", function(options) {
|
740
746
|
options = defaults(options, {
|
741
747
|
eval : false,
|
748
|
+
nth_identifier : base54,
|
742
749
|
ie8 : false,
|
743
750
|
keep_classnames: false,
|
744
751
|
keep_fnames : false,
|
@@ -760,6 +767,7 @@ AST_Toplevel.DEFMETHOD("_default_mangler_options", function(options) {
|
|
760
767
|
|
761
768
|
AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
|
762
769
|
options = this._default_mangler_options(options);
|
770
|
+
var nth_identifier = options.nth_identifier;
|
763
771
|
|
764
772
|
// We only need to mangle declaration nodes. Special logic wired
|
765
773
|
// into the code generator will display the mangled name if it's
|
@@ -811,8 +819,8 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
|
|
811
819
|
if (node instanceof AST_Label) {
|
812
820
|
let name;
|
813
821
|
do {
|
814
|
-
name =
|
815
|
-
} while (
|
822
|
+
name = nth_identifier.get(++lname);
|
823
|
+
} while (ALL_RESERVED_WORDS.has(name));
|
816
824
|
node.mangled_name = name;
|
817
825
|
return true;
|
818
826
|
}
|
@@ -873,9 +881,12 @@ AST_Toplevel.DEFMETHOD("find_colliding_names", function(options) {
|
|
873
881
|
});
|
874
882
|
|
875
883
|
AST_Toplevel.DEFMETHOD("expand_names", function(options) {
|
876
|
-
base54.reset();
|
877
|
-
base54.sort();
|
878
884
|
options = this._default_mangler_options(options);
|
885
|
+
var nth_identifier = options.nth_identifier;
|
886
|
+
if (nth_identifier.reset && nth_identifier.sort) {
|
887
|
+
nth_identifier.reset();
|
888
|
+
nth_identifier.sort();
|
889
|
+
}
|
879
890
|
var avoid = this.find_colliding_names(options);
|
880
891
|
var cname = 0;
|
881
892
|
this.globals.forEach(rename);
|
@@ -887,8 +898,8 @@ AST_Toplevel.DEFMETHOD("expand_names", function(options) {
|
|
887
898
|
function next_name() {
|
888
899
|
var name;
|
889
900
|
do {
|
890
|
-
name =
|
891
|
-
} while (avoid.has(name) ||
|
901
|
+
name = nth_identifier.get(cname++);
|
902
|
+
} while (avoid.has(name) || ALL_RESERVED_WORDS.has(name));
|
892
903
|
return name;
|
893
904
|
}
|
894
905
|
|
@@ -914,30 +925,37 @@ AST_Sequence.DEFMETHOD("tail_node", function() {
|
|
914
925
|
|
915
926
|
AST_Toplevel.DEFMETHOD("compute_char_frequency", function(options) {
|
916
927
|
options = this._default_mangler_options(options);
|
928
|
+
var nth_identifier = options.nth_identifier;
|
929
|
+
if (!nth_identifier.reset || !nth_identifier.consider || !nth_identifier.sort) {
|
930
|
+
// If the identifier mangler is invariant, skip computing character frequency.
|
931
|
+
return;
|
932
|
+
}
|
933
|
+
nth_identifier.reset();
|
934
|
+
|
917
935
|
try {
|
918
936
|
AST_Node.prototype.print = function(stream, force_parens) {
|
919
937
|
this._print(stream, force_parens);
|
920
938
|
if (this instanceof AST_Symbol && !this.unmangleable(options)) {
|
921
|
-
|
939
|
+
nth_identifier.consider(this.name, -1);
|
922
940
|
} else if (options.properties) {
|
923
941
|
if (this instanceof AST_DotHash) {
|
924
|
-
|
942
|
+
nth_identifier.consider("#" + this.property, -1);
|
925
943
|
} else if (this instanceof AST_Dot) {
|
926
|
-
|
944
|
+
nth_identifier.consider(this.property, -1);
|
927
945
|
} else if (this instanceof AST_Sub) {
|
928
946
|
skip_string(this.property);
|
929
947
|
}
|
930
948
|
}
|
931
949
|
};
|
932
|
-
|
950
|
+
nth_identifier.consider(this.print_to_string(), 1);
|
933
951
|
} finally {
|
934
952
|
AST_Node.prototype.print = AST_Node.prototype._print;
|
935
953
|
}
|
936
|
-
|
954
|
+
nth_identifier.sort();
|
937
955
|
|
938
956
|
function skip_string(node) {
|
939
957
|
if (node instanceof AST_String) {
|
940
|
-
|
958
|
+
nth_identifier.consider(node.value, -1);
|
941
959
|
} else if (node instanceof AST_Conditional) {
|
942
960
|
skip_string(node.consequent);
|
943
961
|
skip_string(node.alternative);
|
@@ -961,19 +979,20 @@ const base54 = (() => {
|
|
961
979
|
frequency.set(ch, 0);
|
962
980
|
});
|
963
981
|
}
|
964
|
-
|
982
|
+
function consider(str, delta) {
|
965
983
|
for (var i = str.length; --i >= 0;) {
|
966
984
|
frequency.set(str[i], frequency.get(str[i]) + delta);
|
967
985
|
}
|
968
|
-
}
|
986
|
+
}
|
969
987
|
function compare(a, b) {
|
970
988
|
return frequency.get(b) - frequency.get(a);
|
971
989
|
}
|
972
|
-
|
990
|
+
function sort() {
|
973
991
|
chars = mergeSort(leading, compare).concat(mergeSort(digits, compare));
|
974
|
-
}
|
975
|
-
|
992
|
+
}
|
993
|
+
// Ensure this is in a usable initial state.
|
976
994
|
reset();
|
995
|
+
sort();
|
977
996
|
function base54(num) {
|
978
997
|
var ret = "", base = 54;
|
979
998
|
num++;
|
@@ -985,7 +1004,13 @@ const base54 = (() => {
|
|
985
1004
|
} while (num > 0);
|
986
1005
|
return ret;
|
987
1006
|
}
|
988
|
-
|
1007
|
+
|
1008
|
+
return {
|
1009
|
+
get: base54,
|
1010
|
+
consider,
|
1011
|
+
reset,
|
1012
|
+
sort
|
1013
|
+
};
|
989
1014
|
})();
|
990
1015
|
|
991
1016
|
export {
|
package/lib/transform.js
CHANGED
@@ -57,7 +57,6 @@ import {
|
|
57
57
|
AST_Definitions,
|
58
58
|
AST_Destructuring,
|
59
59
|
AST_Do,
|
60
|
-
AST_Dot,
|
61
60
|
AST_Exit,
|
62
61
|
AST_Expansion,
|
63
62
|
AST_Export,
|
@@ -74,6 +73,7 @@ import {
|
|
74
73
|
AST_Object,
|
75
74
|
AST_ObjectProperty,
|
76
75
|
AST_PrefixedTemplateString,
|
76
|
+
AST_PropAccess,
|
77
77
|
AST_Sequence,
|
78
78
|
AST_SimpleStatement,
|
79
79
|
AST_Sub,
|
@@ -228,7 +228,7 @@ def_transform(AST_Sequence, function(self, tw) {
|
|
228
228
|
: [new AST_Number({ value: 0 })];
|
229
229
|
});
|
230
230
|
|
231
|
-
def_transform(
|
231
|
+
def_transform(AST_PropAccess, function(self, tw) {
|
232
232
|
self.expression = self.expression.transform(tw);
|
233
233
|
});
|
234
234
|
|
package/lib/utils/index.js
CHANGED
@@ -64,10 +64,8 @@ class DefaultsError extends Error {
|
|
64
64
|
function defaults(args, defs, croak) {
|
65
65
|
if (args === true) {
|
66
66
|
args = {};
|
67
|
-
}
|
68
|
-
|
69
|
-
if (args != null && typeof args === "object") {
|
70
|
-
args = Object.assign({}, args);
|
67
|
+
} else if (args != null && typeof args === "object") {
|
68
|
+
args = {...args};
|
71
69
|
}
|
72
70
|
|
73
71
|
const ret = args || {};
|
@@ -196,7 +194,7 @@ function mergeSort(array, cmp) {
|
|
196
194
|
function makePredicate(words) {
|
197
195
|
if (!Array.isArray(words)) words = words.split(" ");
|
198
196
|
|
199
|
-
return new Set(words);
|
197
|
+
return new Set(words.sort());
|
200
198
|
}
|
201
199
|
|
202
200
|
function map_add(map, key, value) {
|
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.
|
7
|
+
"version": "5.8.0",
|
8
8
|
"engines": {
|
9
9
|
"node": ">=10"
|
10
10
|
},
|
@@ -24,7 +24,8 @@
|
|
24
24
|
"./dist/bundle.min.js"
|
25
25
|
],
|
26
26
|
"./package": "./package.json",
|
27
|
-
"./package.json": "./package.json"
|
27
|
+
"./package.json": "./package.json",
|
28
|
+
"./bin/terser": "./bin/terser"
|
28
29
|
},
|
29
30
|
"types": "tools/terser.d.ts",
|
30
31
|
"bin": {
|
@@ -44,19 +45,19 @@
|
|
44
45
|
"dependencies": {
|
45
46
|
"commander": "^2.20.0",
|
46
47
|
"source-map": "~0.7.2",
|
47
|
-
"source-map-support": "~0.5.
|
48
|
+
"source-map-support": "~0.5.20"
|
48
49
|
},
|
49
50
|
"devDependencies": {
|
50
|
-
"@ls-lint/ls-lint": "^1.
|
51
|
-
"acorn": "^8.0
|
52
|
-
"astring": "^1.
|
53
|
-
"eslint": "^7.
|
54
|
-
"eslump": "^
|
51
|
+
"@ls-lint/ls-lint": "^1.10.0",
|
52
|
+
"acorn": "^8.5.0",
|
53
|
+
"astring": "^1.7.5",
|
54
|
+
"eslint": "^7.32.0",
|
55
|
+
"eslump": "^3.0.0",
|
55
56
|
"esm": "^3.2.25",
|
56
|
-
"mocha": "^
|
57
|
+
"mocha": "^9.1.1",
|
57
58
|
"pre-commit": "^1.2.2",
|
58
59
|
"rimraf": "^3.0.2",
|
59
|
-
"rollup": "2.
|
60
|
+
"rollup": "2.56.3",
|
60
61
|
"semver": "^7.3.4"
|
61
62
|
},
|
62
63
|
"scripts": {
|
@@ -92,7 +93,7 @@
|
|
92
93
|
"eslintConfig": {
|
93
94
|
"parserOptions": {
|
94
95
|
"sourceType": "module",
|
95
|
-
"ecmaVersion":
|
96
|
+
"ecmaVersion": 2020
|
96
97
|
},
|
97
98
|
"env": {
|
98
99
|
"node": true,
|
@@ -124,7 +125,7 @@
|
|
124
125
|
"no-unused-vars": [
|
125
126
|
"error",
|
126
127
|
{
|
127
|
-
"varsIgnorePattern": "^_
|
128
|
+
"varsIgnorePattern": "^_"
|
128
129
|
}
|
129
130
|
],
|
130
131
|
"no-tabs": "error",
|
package/tools/terser.d.ts
CHANGED
@@ -80,16 +80,52 @@ export interface MangleOptions {
|
|
80
80
|
keep_classnames?: boolean | RegExp;
|
81
81
|
keep_fnames?: boolean | RegExp;
|
82
82
|
module?: boolean;
|
83
|
+
nth_identifier?: SimpleIdentifierMangler | WeightedIdentifierMangler;
|
83
84
|
properties?: boolean | ManglePropertiesOptions;
|
84
85
|
reserved?: string[];
|
85
86
|
safari10?: boolean;
|
86
87
|
toplevel?: boolean;
|
87
88
|
}
|
88
89
|
|
90
|
+
/**
|
91
|
+
* An identifier mangler for which the output is invariant with respect to the source code.
|
92
|
+
*/
|
93
|
+
export interface SimpleIdentifierMangler {
|
94
|
+
/**
|
95
|
+
* Obtains the nth most favored (usually shortest) identifier to rename a variable to.
|
96
|
+
* The mangler will increment n and retry until the return value is not in use in scope, and is not a reserved word.
|
97
|
+
* This function is expected to be stable; Evaluating get(n) === get(n) should always return true.
|
98
|
+
* @param n The ordinal of the identifier.
|
99
|
+
*/
|
100
|
+
get(n: number): string;
|
101
|
+
}
|
102
|
+
|
103
|
+
/**
|
104
|
+
* An identifier mangler that leverages character frequency analysis to determine identifier precedence.
|
105
|
+
*/
|
106
|
+
export interface WeightedIdentifierMangler extends SimpleIdentifierMangler {
|
107
|
+
/**
|
108
|
+
* Modifies the internal weighting of the input characters by the specified delta.
|
109
|
+
* Will be invoked on the entire printed AST, and then deduct mangleable identifiers.
|
110
|
+
* @param chars The characters to modify the weighting of.
|
111
|
+
* @param delta The numeric weight to add to the characters.
|
112
|
+
*/
|
113
|
+
consider(chars: string, delta: number): number;
|
114
|
+
/**
|
115
|
+
* Resets character weights.
|
116
|
+
*/
|
117
|
+
reset(): void;
|
118
|
+
/**
|
119
|
+
* Sorts identifiers by character frequency, in preparation for calls to get(n).
|
120
|
+
*/
|
121
|
+
sort(): void;
|
122
|
+
}
|
123
|
+
|
89
124
|
export interface ManglePropertiesOptions {
|
90
125
|
builtins?: boolean;
|
91
126
|
debug?: boolean;
|
92
127
|
keep_quoted?: boolean | 'strict';
|
128
|
+
nth_identifier?: SimpleIdentifierMangler | WeightedIdentifierMangler;
|
93
129
|
regex?: RegExp | string;
|
94
130
|
reserved?: string[];
|
95
131
|
}
|
@@ -138,6 +174,7 @@ export enum OutputQuoteStyle {
|
|
138
174
|
export interface MinifyOptions {
|
139
175
|
compress?: boolean | CompressOptions;
|
140
176
|
ecma?: ECMA;
|
177
|
+
enclose?: boolean | string;
|
141
178
|
ie8?: boolean;
|
142
179
|
keep_classnames?: boolean | RegExp;
|
143
180
|
keep_fnames?: boolean | RegExp;
|