terser 4.8.0 → 5.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.
@@ -0,0 +1,302 @@
1
+ import {
2
+ AST_Array,
3
+ AST_Atom,
4
+ AST_Await,
5
+ AST_BigInt,
6
+ AST_Binary,
7
+ AST_Block,
8
+ AST_Call,
9
+ AST_Catch,
10
+ AST_Class,
11
+ AST_ClassProperty,
12
+ AST_ConciseMethod,
13
+ AST_Conditional,
14
+ AST_Debugger,
15
+ AST_Definitions,
16
+ AST_Destructuring,
17
+ AST_Directive,
18
+ AST_Do,
19
+ AST_Dot,
20
+ AST_EmptyStatement,
21
+ AST_Expansion,
22
+ AST_Export,
23
+ AST_Finally,
24
+ AST_For,
25
+ AST_ForIn,
26
+ AST_ForOf,
27
+ AST_If,
28
+ AST_Import,
29
+ AST_Jump,
30
+ AST_LabeledStatement,
31
+ AST_Lambda,
32
+ AST_LoopControl,
33
+ AST_NameMapping,
34
+ AST_NewTarget,
35
+ AST_Node,
36
+ AST_Number,
37
+ AST_Object,
38
+ AST_ObjectGetter,
39
+ AST_ObjectKeyVal,
40
+ AST_ObjectProperty,
41
+ AST_ObjectSetter,
42
+ AST_PrefixedTemplateString,
43
+ AST_PropAccess,
44
+ AST_RegExp,
45
+ AST_Sequence,
46
+ AST_SimpleStatement,
47
+ AST_String,
48
+ AST_Super,
49
+ AST_Switch,
50
+ AST_SwitchBranch,
51
+ AST_Symbol,
52
+ AST_TemplateSegment,
53
+ AST_TemplateString,
54
+ AST_This,
55
+ AST_Toplevel,
56
+ AST_Try,
57
+ AST_Unary,
58
+ AST_VarDef,
59
+ AST_While,
60
+ AST_With,
61
+ AST_Yield
62
+ } from "./ast.js";
63
+
64
+ const shallow_cmp = (node1, node2) => {
65
+ return (
66
+ node1 === null && node2 === null
67
+ || node1.TYPE === node2.TYPE && node1.shallow_cmp(node2)
68
+ );
69
+ };
70
+
71
+ export const equivalent_to = (tree1, tree2) => {
72
+ if (!shallow_cmp(tree1, tree2)) return false;
73
+ const walk_1_state = [tree1];
74
+ const walk_2_state = [tree2];
75
+
76
+ const walk_1_push = walk_1_state.push.bind(walk_1_state);
77
+ const walk_2_push = walk_2_state.push.bind(walk_2_state);
78
+
79
+ while (walk_1_state.length && walk_2_state.length) {
80
+ const node_1 = walk_1_state.pop();
81
+ const node_2 = walk_2_state.pop();
82
+
83
+ if (!shallow_cmp(node_1, node_2)) return false;
84
+
85
+ node_1._children_backwards(walk_1_push);
86
+ node_2._children_backwards(walk_2_push);
87
+
88
+ if (walk_1_state.length !== walk_2_state.length) {
89
+ // Different number of children
90
+ return false;
91
+ }
92
+ }
93
+
94
+ return walk_1_state.length == 0 && walk_2_state.length == 0;
95
+ };
96
+
97
+ // Creates a shallow compare function
98
+ const mkshallow = (props) => {
99
+ const comparisons = Object
100
+ .keys(props)
101
+ .map(key => {
102
+ if (props[key] === "eq") {
103
+ return `this.${key} === other.${key}`;
104
+ } else if (props[key] === "exist") {
105
+ return `(this.${key} == null ? other.${key} == null : this.${key} === other.${key})`;
106
+ } else {
107
+ throw new Error(`mkshallow: Unexpected instruction: ${props[key]}`);
108
+ }
109
+ })
110
+ .join(" && ");
111
+
112
+ return new Function("other", "return " + comparisons);
113
+ };
114
+
115
+ const pass_through = () => true;
116
+
117
+ AST_Node.prototype.shallow_cmp = function () {
118
+ throw new Error("did not find a shallow_cmp function for " + this.constructor.name);
119
+ };
120
+
121
+ AST_Debugger.prototype.shallow_cmp = pass_through;
122
+
123
+ AST_Directive.prototype.shallow_cmp = mkshallow({ value: "eq" });
124
+
125
+ AST_SimpleStatement.prototype.shallow_cmp = pass_through;
126
+
127
+ AST_Block.prototype.shallow_cmp = pass_through;
128
+
129
+ AST_EmptyStatement.prototype.shallow_cmp = pass_through;
130
+
131
+ AST_LabeledStatement.prototype.shallow_cmp = mkshallow({ "label.name": "eq" });
132
+
133
+ AST_Do.prototype.shallow_cmp = pass_through;
134
+
135
+ AST_While.prototype.shallow_cmp = pass_through;
136
+
137
+ AST_For.prototype.shallow_cmp = mkshallow({
138
+ init: "exist",
139
+ condition: "exist",
140
+ step: "exist"
141
+ });
142
+
143
+ AST_ForIn.prototype.shallow_cmp = pass_through;
144
+
145
+ AST_ForOf.prototype.shallow_cmp = pass_through;
146
+
147
+ AST_With.prototype.shallow_cmp = pass_through;
148
+
149
+ AST_Toplevel.prototype.shallow_cmp = pass_through;
150
+
151
+ AST_Expansion.prototype.shallow_cmp = pass_through;
152
+
153
+ AST_Lambda.prototype.shallow_cmp = mkshallow({
154
+ is_generator: "eq",
155
+ async: "eq"
156
+ });
157
+
158
+ AST_Destructuring.prototype.shallow_cmp = mkshallow({
159
+ is_array: "eq"
160
+ });
161
+
162
+ AST_PrefixedTemplateString.prototype.shallow_cmp = pass_through;
163
+
164
+ AST_TemplateString.prototype.shallow_cmp = pass_through;
165
+
166
+ AST_TemplateSegment.prototype.shallow_cmp = mkshallow({
167
+ "value": "eq"
168
+ });
169
+
170
+ AST_Jump.prototype.shallow_cmp = pass_through;
171
+
172
+ AST_LoopControl.prototype.shallow_cmp = pass_through;
173
+
174
+ AST_Await.prototype.shallow_cmp = pass_through;
175
+
176
+ AST_Yield.prototype.shallow_cmp = mkshallow({
177
+ is_star: "eq"
178
+ });
179
+
180
+ AST_If.prototype.shallow_cmp = mkshallow({
181
+ alternative: "exist"
182
+ });
183
+
184
+ AST_Switch.prototype.shallow_cmp = pass_through;
185
+
186
+ AST_SwitchBranch.prototype.shallow_cmp = pass_through;
187
+
188
+ AST_Try.prototype.shallow_cmp = mkshallow({
189
+ bcatch: "exist",
190
+ bfinally: "exist"
191
+ });
192
+
193
+ AST_Catch.prototype.shallow_cmp = mkshallow({
194
+ argname: "exist"
195
+ });
196
+
197
+ AST_Finally.prototype.shallow_cmp = pass_through;
198
+
199
+ AST_Definitions.prototype.shallow_cmp = pass_through;
200
+
201
+ AST_VarDef.prototype.shallow_cmp = mkshallow({
202
+ value: "exist"
203
+ });
204
+
205
+ AST_NameMapping.prototype.shallow_cmp = pass_through;
206
+
207
+ AST_Import.prototype.shallow_cmp = mkshallow({
208
+ imported_name: "exist",
209
+ imported_names: "exist"
210
+ });
211
+
212
+ AST_Export.prototype.shallow_cmp = mkshallow({
213
+ exported_definition: "exist",
214
+ exported_value: "exist",
215
+ exported_names: "exist",
216
+ module_name: "eq",
217
+ is_default: "eq",
218
+ });
219
+
220
+ AST_Call.prototype.shallow_cmp = pass_through;
221
+
222
+ AST_Sequence.prototype.shallow_cmp = pass_through;
223
+
224
+ AST_PropAccess.prototype.shallow_cmp = pass_through;
225
+
226
+ AST_Dot.prototype.shallow_cmp = mkshallow({
227
+ property: "eq"
228
+ });
229
+
230
+ AST_Unary.prototype.shallow_cmp = mkshallow({
231
+ operator: "eq"
232
+ });
233
+
234
+ AST_Binary.prototype.shallow_cmp = mkshallow({
235
+ operator: "eq"
236
+ });
237
+
238
+ AST_Conditional.prototype.shallow_cmp = pass_through;
239
+
240
+ AST_Array.prototype.shallow_cmp = pass_through;
241
+
242
+ AST_Object.prototype.shallow_cmp = pass_through;
243
+
244
+ AST_ObjectProperty.prototype.shallow_cmp = pass_through;
245
+
246
+ AST_ObjectKeyVal.prototype.shallow_cmp = mkshallow({
247
+ key: "eq"
248
+ });
249
+
250
+ AST_ObjectSetter.prototype.shallow_cmp = mkshallow({
251
+ static: "eq"
252
+ });
253
+
254
+ AST_ObjectGetter.prototype.shallow_cmp = mkshallow({
255
+ static: "eq"
256
+ });
257
+
258
+ AST_ConciseMethod.prototype.shallow_cmp = mkshallow({
259
+ static: "eq",
260
+ is_generator: "eq",
261
+ async: "eq",
262
+ });
263
+
264
+ AST_Class.prototype.shallow_cmp = mkshallow({
265
+ name: "exist",
266
+ extends: "exist",
267
+ });
268
+
269
+ AST_ClassProperty.prototype.shallow_cmp = mkshallow({
270
+ static: "eq"
271
+ });
272
+
273
+ AST_Symbol.prototype.shallow_cmp = mkshallow({
274
+ name: "eq"
275
+ });
276
+
277
+ AST_NewTarget.prototype.shallow_cmp = pass_through;
278
+
279
+ AST_This.prototype.shallow_cmp = pass_through;
280
+
281
+ AST_Super.prototype.shallow_cmp = pass_through;
282
+
283
+ AST_String.prototype.shallow_cmp = mkshallow({
284
+ value: "eq"
285
+ });
286
+
287
+ AST_Number.prototype.shallow_cmp = mkshallow({
288
+ value: "eq"
289
+ });
290
+
291
+ AST_BigInt.prototype.shallow_cmp = mkshallow({
292
+ value: "eq"
293
+ });
294
+
295
+ AST_RegExp.prototype.shallow_cmp = function (other) {
296
+ return (
297
+ this.value.flags === other.value.flags
298
+ && this.value.source === other.value.source
299
+ );
300
+ };
301
+
302
+ AST_Atom.prototype.shallow_cmp = pass_through;
package/lib/minify.js ADDED
@@ -0,0 +1,264 @@
1
+ "use strict";
2
+ /* eslint-env browser, es6, node */
3
+
4
+ import {
5
+ defaults,
6
+ map_from_object,
7
+ map_to_object,
8
+ HOP,
9
+ } from "./utils/index.js";
10
+ import { AST_Toplevel } from "./ast.js";
11
+ import { parse } from "./parse.js";
12
+ import { OutputStream } from "./output.js";
13
+ import { Compressor } from "./compress/index.js";
14
+ import { base54 } from "./scope.js";
15
+ import { SourceMap } from "./sourcemap.js";
16
+ import {
17
+ mangle_properties,
18
+ reserve_quoted_keys,
19
+ } from "./propmangle.js";
20
+
21
+ var to_ascii = typeof atob == "undefined" ? function(b64) {
22
+ return Buffer.from(b64, "base64").toString();
23
+ } : atob;
24
+ var to_base64 = typeof btoa == "undefined" ? function(str) {
25
+ return Buffer.from(str).toString("base64");
26
+ } : btoa;
27
+
28
+ function read_source_map(code) {
29
+ var match = /(?:^|[^.])\/\/# sourceMappingURL=data:application\/json(;[\w=-]*)?;base64,([+/0-9A-Za-z]*=*)\s*$/.exec(code);
30
+ if (!match) {
31
+ console.warn("inline source map not found");
32
+ return null;
33
+ }
34
+ return to_ascii(match[2]);
35
+ }
36
+
37
+ function set_shorthand(name, options, keys) {
38
+ if (options[name]) {
39
+ keys.forEach(function(key) {
40
+ if (options[key]) {
41
+ if (typeof options[key] != "object") options[key] = {};
42
+ if (!(name in options[key])) options[key][name] = options[name];
43
+ }
44
+ });
45
+ }
46
+ }
47
+
48
+ function init_cache(cache) {
49
+ if (!cache) return;
50
+ if (!("props" in cache)) {
51
+ cache.props = new Map();
52
+ } else if (!(cache.props instanceof Map)) {
53
+ cache.props = map_from_object(cache.props);
54
+ }
55
+ }
56
+
57
+ function cache_to_json(cache) {
58
+ return {
59
+ props: map_to_object(cache.props)
60
+ };
61
+ }
62
+
63
+ async function minify(files, options) {
64
+ options = defaults(options, {
65
+ compress: {},
66
+ ecma: undefined,
67
+ enclose: false,
68
+ ie8: false,
69
+ keep_classnames: undefined,
70
+ keep_fnames: false,
71
+ mangle: {},
72
+ module: false,
73
+ nameCache: null,
74
+ output: null,
75
+ format: null,
76
+ parse: {},
77
+ rename: undefined,
78
+ safari10: false,
79
+ sourceMap: false,
80
+ timings: false,
81
+ toplevel: false,
82
+ warnings: false,
83
+ wrap: false,
84
+ }, true);
85
+ var timings = options.timings && {
86
+ start: Date.now()
87
+ };
88
+ if (options.keep_classnames === undefined) {
89
+ options.keep_classnames = options.keep_fnames;
90
+ }
91
+ if (options.rename === undefined) {
92
+ options.rename = options.compress && options.mangle;
93
+ }
94
+ if (options.output && options.format) {
95
+ throw new Error("Please only specify either output or format option, preferrably format.");
96
+ }
97
+ options.format = options.format || options.output || {};
98
+ set_shorthand("ecma", options, [ "parse", "compress", "format" ]);
99
+ set_shorthand("ie8", options, [ "compress", "mangle", "format" ]);
100
+ set_shorthand("keep_classnames", options, [ "compress", "mangle" ]);
101
+ set_shorthand("keep_fnames", options, [ "compress", "mangle" ]);
102
+ set_shorthand("module", options, [ "parse", "compress", "mangle" ]);
103
+ set_shorthand("safari10", options, [ "mangle", "format" ]);
104
+ set_shorthand("toplevel", options, [ "compress", "mangle" ]);
105
+ set_shorthand("warnings", options, [ "compress" ]); // legacy
106
+ var quoted_props;
107
+ if (options.mangle) {
108
+ options.mangle = defaults(options.mangle, {
109
+ cache: options.nameCache && (options.nameCache.vars || {}),
110
+ eval: false,
111
+ ie8: false,
112
+ keep_classnames: false,
113
+ keep_fnames: false,
114
+ module: false,
115
+ properties: false,
116
+ reserved: [],
117
+ safari10: false,
118
+ toplevel: false,
119
+ }, true);
120
+ if (options.mangle.properties) {
121
+ if (typeof options.mangle.properties != "object") {
122
+ options.mangle.properties = {};
123
+ }
124
+ if (options.mangle.properties.keep_quoted) {
125
+ quoted_props = options.mangle.properties.reserved;
126
+ if (!Array.isArray(quoted_props)) quoted_props = [];
127
+ options.mangle.properties.reserved = quoted_props;
128
+ }
129
+ if (options.nameCache && !("cache" in options.mangle.properties)) {
130
+ options.mangle.properties.cache = options.nameCache.props || {};
131
+ }
132
+ }
133
+ init_cache(options.mangle.cache);
134
+ init_cache(options.mangle.properties.cache);
135
+ }
136
+ if (options.sourceMap) {
137
+ options.sourceMap = defaults(options.sourceMap, {
138
+ asObject: false,
139
+ content: null,
140
+ filename: null,
141
+ includeSources: false,
142
+ root: null,
143
+ url: null,
144
+ }, true);
145
+ }
146
+ if (timings) timings.parse = Date.now();
147
+ var toplevel;
148
+ if (files instanceof AST_Toplevel) {
149
+ toplevel = files;
150
+ } else {
151
+ if (typeof files == "string") {
152
+ files = [ files ];
153
+ }
154
+ options.parse = options.parse || {};
155
+ options.parse.toplevel = null;
156
+ for (var name in files) if (HOP(files, name)) {
157
+ options.parse.filename = name;
158
+ options.parse.toplevel = parse(files[name], options.parse);
159
+ if (options.sourceMap && options.sourceMap.content == "inline") {
160
+ if (Object.keys(files).length > 1)
161
+ throw new Error("inline source map only works with singular input");
162
+ options.sourceMap.content = read_source_map(files[name]);
163
+ }
164
+ }
165
+ toplevel = options.parse.toplevel;
166
+ }
167
+ if (quoted_props && options.mangle.properties.keep_quoted !== "strict") {
168
+ reserve_quoted_keys(toplevel, quoted_props);
169
+ }
170
+ if (options.wrap) {
171
+ toplevel = toplevel.wrap_commonjs(options.wrap);
172
+ }
173
+ if (options.enclose) {
174
+ toplevel = toplevel.wrap_enclose(options.enclose);
175
+ }
176
+ if (timings) timings.rename = Date.now();
177
+ // disable rename on harmony due to expand_names bug in for-of loops
178
+ // https://github.com/mishoo/UglifyJS2/issues/2794
179
+ if (0 && options.rename) {
180
+ toplevel.figure_out_scope(options.mangle);
181
+ toplevel.expand_names(options.mangle);
182
+ }
183
+ if (timings) timings.compress = Date.now();
184
+ if (options.compress) toplevel = new Compressor(options.compress).compress(toplevel);
185
+ if (timings) timings.scope = Date.now();
186
+ if (options.mangle) toplevel.figure_out_scope(options.mangle);
187
+ if (timings) timings.mangle = Date.now();
188
+ if (options.mangle) {
189
+ base54.reset();
190
+ toplevel.compute_char_frequency(options.mangle);
191
+ toplevel.mangle_names(options.mangle);
192
+ }
193
+ if (timings) timings.properties = Date.now();
194
+ if (options.mangle && options.mangle.properties) {
195
+ toplevel = mangle_properties(toplevel, options.mangle.properties);
196
+ }
197
+ if (timings) timings.format = Date.now();
198
+ var result = {};
199
+ if (options.format.ast) {
200
+ result.ast = toplevel;
201
+ }
202
+ if (!HOP(options.format, "code") || options.format.code) {
203
+ if (options.sourceMap) {
204
+ if (typeof options.sourceMap.content == "string") {
205
+ options.sourceMap.content = JSON.parse(options.sourceMap.content);
206
+ }
207
+ options.format.source_map = SourceMap({
208
+ file: options.sourceMap.filename,
209
+ orig: options.sourceMap.content,
210
+ root: options.sourceMap.root
211
+ });
212
+ if (options.sourceMap.includeSources) {
213
+ if (files instanceof AST_Toplevel) {
214
+ throw new Error("original source content unavailable");
215
+ } else for (var name in files) if (HOP(files, name)) {
216
+ options.format.source_map.get().setSourceContent(name, files[name]);
217
+ }
218
+ }
219
+ }
220
+ delete options.format.ast;
221
+ delete options.format.code;
222
+ var stream = OutputStream(options.format);
223
+ toplevel.print(stream);
224
+ result.code = stream.get();
225
+ if (options.sourceMap) {
226
+ if(options.sourceMap.asObject) {
227
+ result.map = options.format.source_map.get().toJSON();
228
+ } else {
229
+ result.map = options.format.source_map.toString();
230
+ }
231
+ if (options.sourceMap.url == "inline") {
232
+ var sourceMap = typeof result.map === "object" ? JSON.stringify(result.map) : result.map;
233
+ result.code += "\n//# sourceMappingURL=data:application/json;charset=utf-8;base64," + to_base64(sourceMap);
234
+ } else if (options.sourceMap.url) {
235
+ result.code += "\n//# sourceMappingURL=" + options.sourceMap.url;
236
+ }
237
+ }
238
+ }
239
+ if (options.nameCache && options.mangle) {
240
+ if (options.mangle.cache) options.nameCache.vars = cache_to_json(options.mangle.cache);
241
+ if (options.mangle.properties && options.mangle.properties.cache) {
242
+ options.nameCache.props = cache_to_json(options.mangle.properties.cache);
243
+ }
244
+ }
245
+ if (timings) {
246
+ timings.end = Date.now();
247
+ result.timings = {
248
+ parse: 1e-3 * (timings.rename - timings.parse),
249
+ rename: 1e-3 * (timings.compress - timings.rename),
250
+ compress: 1e-3 * (timings.scope - timings.compress),
251
+ scope: 1e-3 * (timings.mangle - timings.scope),
252
+ mangle: 1e-3 * (timings.properties - timings.mangle),
253
+ properties: 1e-3 * (timings.format - timings.properties),
254
+ format: 1e-3 * (timings.end - timings.format),
255
+ total: 1e-3 * (timings.end - timings.start)
256
+ };
257
+ }
258
+ return result;
259
+ }
260
+
261
+ export {
262
+ minify,
263
+ to_ascii,
264
+ };