terser 5.9.0 → 5.14.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.
- package/CHANGELOG.md +63 -0
- package/README.md +30 -8
- package/dist/bundle.min.js +5407 -3433
- package/lib/ast.js +1685 -348
- package/lib/cli.js +13 -9
- package/lib/compress/common.js +48 -0
- package/lib/compress/evaluate.js +18 -17
- package/lib/compress/index.js +57 -551
- package/lib/compress/inline.js +641 -0
- package/lib/compress/native-objects.js +1 -0
- package/lib/compress/tighten-body.js +1 -1
- package/lib/equivalent-to.js +81 -107
- package/lib/minify.js +96 -15
- package/lib/mozilla-ast.js +522 -87
- package/lib/output.js +94 -24
- package/lib/parse.js +91 -72
- package/lib/propmangle.js +1 -1
- package/lib/scope.js +27 -4
- package/lib/size.js +6 -8
- package/lib/sourcemap.js +60 -26
- package/lib/utils/index.js +9 -1
- package/package.json +9 -5
- package/tools/domprops.js +12 -0
- package/tools/terser.d.ts +6 -3
package/lib/equivalent-to.js
CHANGED
@@ -97,24 +97,6 @@ export const equivalent_to = (tree1, tree2) => {
|
|
97
97
|
return walk_1_state.length == 0 && walk_2_state.length == 0;
|
98
98
|
};
|
99
99
|
|
100
|
-
// Creates a shallow compare function
|
101
|
-
const mkshallow = (props) => {
|
102
|
-
const comparisons = Object
|
103
|
-
.keys(props)
|
104
|
-
.map(key => {
|
105
|
-
if (props[key] === "eq") {
|
106
|
-
return `this.${key} === other.${key}`;
|
107
|
-
} else if (props[key] === "exist") {
|
108
|
-
return `(this.${key} == null ? other.${key} == null : this.${key} === other.${key})`;
|
109
|
-
} else {
|
110
|
-
throw new Error(`mkshallow: Unexpected instruction: ${props[key]}`);
|
111
|
-
}
|
112
|
-
})
|
113
|
-
.join(" && ");
|
114
|
-
|
115
|
-
return new Function("other", "return " + comparisons);
|
116
|
-
};
|
117
|
-
|
118
100
|
const pass_through = () => true;
|
119
101
|
|
120
102
|
AST_Node.prototype.shallow_cmp = function () {
|
@@ -123,7 +105,9 @@ AST_Node.prototype.shallow_cmp = function () {
|
|
123
105
|
|
124
106
|
AST_Debugger.prototype.shallow_cmp = pass_through;
|
125
107
|
|
126
|
-
AST_Directive.prototype.shallow_cmp =
|
108
|
+
AST_Directive.prototype.shallow_cmp = function(other) {
|
109
|
+
return this.value === other.value;
|
110
|
+
};
|
127
111
|
|
128
112
|
AST_SimpleStatement.prototype.shallow_cmp = pass_through;
|
129
113
|
|
@@ -131,17 +115,17 @@ AST_Block.prototype.shallow_cmp = pass_through;
|
|
131
115
|
|
132
116
|
AST_EmptyStatement.prototype.shallow_cmp = pass_through;
|
133
117
|
|
134
|
-
AST_LabeledStatement.prototype.shallow_cmp =
|
118
|
+
AST_LabeledStatement.prototype.shallow_cmp = function(other) {
|
119
|
+
return this.label.name === other.label.name;
|
120
|
+
};
|
135
121
|
|
136
122
|
AST_Do.prototype.shallow_cmp = pass_through;
|
137
123
|
|
138
124
|
AST_While.prototype.shallow_cmp = pass_through;
|
139
125
|
|
140
|
-
AST_For.prototype.shallow_cmp =
|
141
|
-
init:
|
142
|
-
|
143
|
-
step: "exist"
|
144
|
-
});
|
126
|
+
AST_For.prototype.shallow_cmp = function(other) {
|
127
|
+
return (this.init == null ? other.init == null : this.init === other.init) && (this.condition == null ? other.condition == null : this.condition === other.condition) && (this.step == null ? other.step == null : this.step === other.step);
|
128
|
+
};
|
145
129
|
|
146
130
|
AST_ForIn.prototype.shallow_cmp = pass_through;
|
147
131
|
|
@@ -153,22 +137,21 @@ AST_Toplevel.prototype.shallow_cmp = pass_through;
|
|
153
137
|
|
154
138
|
AST_Expansion.prototype.shallow_cmp = pass_through;
|
155
139
|
|
156
|
-
AST_Lambda.prototype.shallow_cmp =
|
157
|
-
is_generator
|
158
|
-
|
159
|
-
});
|
140
|
+
AST_Lambda.prototype.shallow_cmp = function(other) {
|
141
|
+
return this.is_generator === other.is_generator && this.async === other.async;
|
142
|
+
};
|
160
143
|
|
161
|
-
AST_Destructuring.prototype.shallow_cmp =
|
162
|
-
is_array
|
163
|
-
}
|
144
|
+
AST_Destructuring.prototype.shallow_cmp = function(other) {
|
145
|
+
return this.is_array === other.is_array;
|
146
|
+
};
|
164
147
|
|
165
148
|
AST_PrefixedTemplateString.prototype.shallow_cmp = pass_through;
|
166
149
|
|
167
150
|
AST_TemplateString.prototype.shallow_cmp = pass_through;
|
168
151
|
|
169
|
-
AST_TemplateSegment.prototype.shallow_cmp =
|
170
|
-
|
171
|
-
}
|
152
|
+
AST_TemplateSegment.prototype.shallow_cmp = function(other) {
|
153
|
+
return this.value === other.value;
|
154
|
+
};
|
172
155
|
|
173
156
|
AST_Jump.prototype.shallow_cmp = pass_through;
|
174
157
|
|
@@ -176,51 +159,45 @@ AST_LoopControl.prototype.shallow_cmp = pass_through;
|
|
176
159
|
|
177
160
|
AST_Await.prototype.shallow_cmp = pass_through;
|
178
161
|
|
179
|
-
AST_Yield.prototype.shallow_cmp =
|
180
|
-
is_star
|
181
|
-
}
|
162
|
+
AST_Yield.prototype.shallow_cmp = function(other) {
|
163
|
+
return this.is_star === other.is_star;
|
164
|
+
};
|
182
165
|
|
183
|
-
AST_If.prototype.shallow_cmp =
|
184
|
-
alternative:
|
185
|
-
}
|
166
|
+
AST_If.prototype.shallow_cmp = function(other) {
|
167
|
+
return this.alternative == null ? other.alternative == null : this.alternative === other.alternative;
|
168
|
+
};
|
186
169
|
|
187
170
|
AST_Switch.prototype.shallow_cmp = pass_through;
|
188
171
|
|
189
172
|
AST_SwitchBranch.prototype.shallow_cmp = pass_through;
|
190
173
|
|
191
|
-
AST_Try.prototype.shallow_cmp =
|
192
|
-
bcatch:
|
193
|
-
|
194
|
-
});
|
174
|
+
AST_Try.prototype.shallow_cmp = function(other) {
|
175
|
+
return (this.bcatch == null ? other.bcatch == null : this.bcatch === other.bcatch) && (this.bfinally == null ? other.bfinally == null : this.bfinally === other.bfinally);
|
176
|
+
};
|
195
177
|
|
196
|
-
AST_Catch.prototype.shallow_cmp =
|
197
|
-
argname:
|
198
|
-
}
|
178
|
+
AST_Catch.prototype.shallow_cmp = function(other) {
|
179
|
+
return this.argname == null ? other.argname == null : this.argname === other.argname;
|
180
|
+
};
|
199
181
|
|
200
182
|
AST_Finally.prototype.shallow_cmp = pass_through;
|
201
183
|
|
202
184
|
AST_Definitions.prototype.shallow_cmp = pass_through;
|
203
185
|
|
204
|
-
AST_VarDef.prototype.shallow_cmp =
|
205
|
-
value:
|
206
|
-
}
|
186
|
+
AST_VarDef.prototype.shallow_cmp = function(other) {
|
187
|
+
return this.value == null ? other.value == null : this.value === other.value;
|
188
|
+
};
|
207
189
|
|
208
190
|
AST_NameMapping.prototype.shallow_cmp = pass_through;
|
209
191
|
|
210
|
-
AST_Import.prototype.shallow_cmp =
|
211
|
-
imported_name:
|
212
|
-
|
213
|
-
});
|
192
|
+
AST_Import.prototype.shallow_cmp = function(other) {
|
193
|
+
return (this.imported_name == null ? other.imported_name == null : this.imported_name === other.imported_name) && (this.imported_names == null ? other.imported_names == null : this.imported_names === other.imported_names);
|
194
|
+
};
|
214
195
|
|
215
196
|
AST_ImportMeta.prototype.shallow_cmp = pass_through;
|
216
197
|
|
217
|
-
AST_Export.prototype.shallow_cmp =
|
218
|
-
exported_definition:
|
219
|
-
|
220
|
-
exported_names: "exist",
|
221
|
-
module_name: "eq",
|
222
|
-
is_default: "eq",
|
223
|
-
});
|
198
|
+
AST_Export.prototype.shallow_cmp = function(other) {
|
199
|
+
return (this.exported_definition == null ? other.exported_definition == null : this.exported_definition === other.exported_definition) && (this.exported_value == null ? other.exported_value == null : this.exported_value === other.exported_value) && (this.exported_names == null ? other.exported_names == null : this.exported_names === other.exported_names) && this.module_name === other.module_name && this.is_default === other.is_default;
|
200
|
+
};
|
224
201
|
|
225
202
|
AST_Call.prototype.shallow_cmp = pass_through;
|
226
203
|
|
@@ -230,21 +207,21 @@ AST_PropAccess.prototype.shallow_cmp = pass_through;
|
|
230
207
|
|
231
208
|
AST_Chain.prototype.shallow_cmp = pass_through;
|
232
209
|
|
233
|
-
AST_Dot.prototype.shallow_cmp =
|
234
|
-
property
|
235
|
-
}
|
210
|
+
AST_Dot.prototype.shallow_cmp = function(other) {
|
211
|
+
return this.property === other.property;
|
212
|
+
};
|
236
213
|
|
237
|
-
AST_DotHash.prototype.shallow_cmp =
|
238
|
-
property
|
239
|
-
}
|
214
|
+
AST_DotHash.prototype.shallow_cmp = function(other) {
|
215
|
+
return this.property === other.property;
|
216
|
+
};
|
240
217
|
|
241
|
-
AST_Unary.prototype.shallow_cmp =
|
242
|
-
operator
|
243
|
-
}
|
218
|
+
AST_Unary.prototype.shallow_cmp = function(other) {
|
219
|
+
return this.operator === other.operator;
|
220
|
+
};
|
244
221
|
|
245
|
-
AST_Binary.prototype.shallow_cmp =
|
246
|
-
operator
|
247
|
-
}
|
222
|
+
AST_Binary.prototype.shallow_cmp = function(other) {
|
223
|
+
return this.operator === other.operator;
|
224
|
+
};
|
248
225
|
|
249
226
|
AST_Conditional.prototype.shallow_cmp = pass_through;
|
250
227
|
|
@@ -254,36 +231,33 @@ AST_Object.prototype.shallow_cmp = pass_through;
|
|
254
231
|
|
255
232
|
AST_ObjectProperty.prototype.shallow_cmp = pass_through;
|
256
233
|
|
257
|
-
AST_ObjectKeyVal.prototype.shallow_cmp =
|
258
|
-
key
|
259
|
-
}
|
234
|
+
AST_ObjectKeyVal.prototype.shallow_cmp = function(other) {
|
235
|
+
return this.key === other.key;
|
236
|
+
};
|
260
237
|
|
261
|
-
AST_ObjectSetter.prototype.shallow_cmp =
|
262
|
-
static
|
263
|
-
}
|
238
|
+
AST_ObjectSetter.prototype.shallow_cmp = function(other) {
|
239
|
+
return this.static === other.static;
|
240
|
+
};
|
264
241
|
|
265
|
-
AST_ObjectGetter.prototype.shallow_cmp =
|
266
|
-
static
|
267
|
-
}
|
242
|
+
AST_ObjectGetter.prototype.shallow_cmp = function(other) {
|
243
|
+
return this.static === other.static;
|
244
|
+
};
|
268
245
|
|
269
|
-
AST_ConciseMethod.prototype.shallow_cmp =
|
270
|
-
static
|
271
|
-
|
272
|
-
async: "eq",
|
273
|
-
});
|
246
|
+
AST_ConciseMethod.prototype.shallow_cmp = function(other) {
|
247
|
+
return this.static === other.static && this.is_generator === other.is_generator && this.async === other.async;
|
248
|
+
};
|
274
249
|
|
275
|
-
AST_Class.prototype.shallow_cmp =
|
276
|
-
name:
|
277
|
-
|
278
|
-
});
|
250
|
+
AST_Class.prototype.shallow_cmp = function(other) {
|
251
|
+
return (this.name == null ? other.name == null : this.name === other.name) && (this.extends == null ? other.extends == null : this.extends === other.extends);
|
252
|
+
};
|
279
253
|
|
280
|
-
AST_ClassProperty.prototype.shallow_cmp =
|
281
|
-
static
|
282
|
-
}
|
254
|
+
AST_ClassProperty.prototype.shallow_cmp = function(other) {
|
255
|
+
return this.static === other.static;
|
256
|
+
};
|
283
257
|
|
284
|
-
AST_Symbol.prototype.shallow_cmp =
|
285
|
-
name
|
286
|
-
}
|
258
|
+
AST_Symbol.prototype.shallow_cmp = function(other) {
|
259
|
+
return this.name === other.name;
|
260
|
+
};
|
287
261
|
|
288
262
|
AST_NewTarget.prototype.shallow_cmp = pass_through;
|
289
263
|
|
@@ -291,17 +265,17 @@ AST_This.prototype.shallow_cmp = pass_through;
|
|
291
265
|
|
292
266
|
AST_Super.prototype.shallow_cmp = pass_through;
|
293
267
|
|
294
|
-
AST_String.prototype.shallow_cmp =
|
295
|
-
value
|
296
|
-
}
|
268
|
+
AST_String.prototype.shallow_cmp = function(other) {
|
269
|
+
return this.value === other.value;
|
270
|
+
};
|
297
271
|
|
298
|
-
AST_Number.prototype.shallow_cmp =
|
299
|
-
value
|
300
|
-
}
|
272
|
+
AST_Number.prototype.shallow_cmp = function(other) {
|
273
|
+
return this.value === other.value;
|
274
|
+
};
|
301
275
|
|
302
|
-
AST_BigInt.prototype.shallow_cmp =
|
303
|
-
value
|
304
|
-
}
|
276
|
+
AST_BigInt.prototype.shallow_cmp = function(other) {
|
277
|
+
return this.value === other.value;
|
278
|
+
};
|
305
279
|
|
306
280
|
AST_RegExp.prototype.shallow_cmp = function (other) {
|
307
281
|
return (
|
package/lib/minify.js
CHANGED
@@ -7,7 +7,7 @@ import {
|
|
7
7
|
map_to_object,
|
8
8
|
HOP,
|
9
9
|
} from "./utils/index.js";
|
10
|
-
import { AST_Toplevel, AST_Node } from "./ast.js";
|
10
|
+
import { AST_Toplevel, AST_Node, walk, AST_Scope } from "./ast.js";
|
11
11
|
import { parse } from "./parse.js";
|
12
12
|
import { OutputStream } from "./output.js";
|
13
13
|
import { Compressor } from "./compress/index.js";
|
@@ -61,7 +61,54 @@ function cache_to_json(cache) {
|
|
61
61
|
};
|
62
62
|
}
|
63
63
|
|
64
|
-
|
64
|
+
function log_input(files, options, fs, debug_folder) {
|
65
|
+
if (!(fs && fs.writeFileSync && fs.mkdirSync)) {
|
66
|
+
return;
|
67
|
+
}
|
68
|
+
|
69
|
+
try {
|
70
|
+
fs.mkdirSync(debug_folder);
|
71
|
+
} catch (e) {
|
72
|
+
if (e.code !== "EEXIST") throw e;
|
73
|
+
}
|
74
|
+
|
75
|
+
const log_path = `${debug_folder}/terser-debug-${(Math.random() * 9999999) | 0}.log`;
|
76
|
+
|
77
|
+
options = options || {};
|
78
|
+
|
79
|
+
const options_str = JSON.stringify(options, (_key, thing) => {
|
80
|
+
if (typeof thing === "function") return "[Function " + thing.toString() + "]";
|
81
|
+
if (thing instanceof RegExp) return "[RegExp " + thing.toString() + "]";
|
82
|
+
return thing;
|
83
|
+
}, 4);
|
84
|
+
|
85
|
+
const files_str = (file) => {
|
86
|
+
if (typeof file === "object" && options.parse && options.parse.spidermonkey) {
|
87
|
+
return JSON.stringify(file, null, 2);
|
88
|
+
} else if (typeof file === "object") {
|
89
|
+
return Object.keys(file)
|
90
|
+
.map((key) => key + ": " + files_str(file[key]))
|
91
|
+
.join("\n\n");
|
92
|
+
} else if (typeof file === "string") {
|
93
|
+
return "```\n" + file + "\n```";
|
94
|
+
} else {
|
95
|
+
return file; // What do?
|
96
|
+
}
|
97
|
+
};
|
98
|
+
|
99
|
+
fs.writeFileSync(log_path, "Options: \n" + options_str + "\n\nInput files:\n\n" + files_str(files) + "\n");
|
100
|
+
}
|
101
|
+
|
102
|
+
async function minify(files, options, _fs_module) {
|
103
|
+
if (
|
104
|
+
_fs_module
|
105
|
+
&& typeof process === "object"
|
106
|
+
&& process.env
|
107
|
+
&& typeof process.env.TERSER_DEBUG_DIR === "string"
|
108
|
+
) {
|
109
|
+
log_input(files, options, _fs_module, process.env.TERSER_DEBUG_DIR);
|
110
|
+
}
|
111
|
+
|
65
112
|
options = defaults(options, {
|
66
113
|
compress: {},
|
67
114
|
ecma: undefined,
|
@@ -84,6 +131,7 @@ async function minify(files, options) {
|
|
84
131
|
warnings: false,
|
85
132
|
wrap: false,
|
86
133
|
}, true);
|
134
|
+
|
87
135
|
var timings = options.timings && {
|
88
136
|
start: Date.now()
|
89
137
|
};
|
@@ -146,6 +194,8 @@ async function minify(files, options) {
|
|
146
194
|
url: null,
|
147
195
|
}, true);
|
148
196
|
}
|
197
|
+
|
198
|
+
// -- Parse phase --
|
149
199
|
if (timings) timings.parse = Date.now();
|
150
200
|
var toplevel;
|
151
201
|
if (files instanceof AST_Toplevel) {
|
@@ -195,12 +245,16 @@ async function minify(files, options) {
|
|
195
245
|
toplevel.figure_out_scope(options.mangle);
|
196
246
|
toplevel.expand_names(options.mangle);
|
197
247
|
}
|
248
|
+
|
249
|
+
// -- Compress phase --
|
198
250
|
if (timings) timings.compress = Date.now();
|
199
251
|
if (options.compress) {
|
200
252
|
toplevel = new Compressor(options.compress, {
|
201
253
|
mangle_options: options.mangle
|
202
254
|
}).compress(toplevel);
|
203
255
|
}
|
256
|
+
|
257
|
+
// -- Mangle phase --
|
204
258
|
if (timings) timings.scope = Date.now();
|
205
259
|
if (options.mangle) toplevel.figure_out_scope(options.mangle);
|
206
260
|
if (timings) timings.mangle = Date.now();
|
@@ -213,6 +267,8 @@ async function minify(files, options) {
|
|
213
267
|
if (options.mangle && options.mangle.properties) {
|
214
268
|
toplevel = mangle_properties(toplevel, options.mangle.properties);
|
215
269
|
}
|
270
|
+
|
271
|
+
// Format phase
|
216
272
|
if (timings) timings.format = Date.now();
|
217
273
|
var result = {};
|
218
274
|
if (options.format.ast) {
|
@@ -222,19 +278,34 @@ async function minify(files, options) {
|
|
222
278
|
result.ast = toplevel.to_mozilla_ast();
|
223
279
|
}
|
224
280
|
if (!HOP(options.format, "code") || options.format.code) {
|
281
|
+
if (!options.format.ast) {
|
282
|
+
// Destroy stuff to save RAM. (unless the deprecated `ast` option is on)
|
283
|
+
options.format._destroy_ast = true;
|
284
|
+
|
285
|
+
walk(toplevel, node => {
|
286
|
+
if (node instanceof AST_Scope) {
|
287
|
+
node.variables = undefined;
|
288
|
+
node.enclosed = undefined;
|
289
|
+
node.parent_scope = undefined;
|
290
|
+
}
|
291
|
+
if (node.block_scope) {
|
292
|
+
node.block_scope.variables = undefined;
|
293
|
+
node.block_scope.enclosed = undefined;
|
294
|
+
node.parent_scope = undefined;
|
295
|
+
}
|
296
|
+
});
|
297
|
+
}
|
298
|
+
|
225
299
|
if (options.sourceMap) {
|
300
|
+
if (options.sourceMap.includeSources && files instanceof AST_Toplevel) {
|
301
|
+
throw new Error("original source content unavailable");
|
302
|
+
}
|
226
303
|
options.format.source_map = await SourceMap({
|
227
304
|
file: options.sourceMap.filename,
|
228
305
|
orig: options.sourceMap.content,
|
229
|
-
root: options.sourceMap.root
|
306
|
+
root: options.sourceMap.root,
|
307
|
+
files: options.sourceMap.includeSources ? files : null,
|
230
308
|
});
|
231
|
-
if (options.sourceMap.includeSources) {
|
232
|
-
if (files instanceof AST_Toplevel) {
|
233
|
-
throw new Error("original source content unavailable");
|
234
|
-
} else for (var name in files) if (HOP(files, name)) {
|
235
|
-
options.format.source_map.get().setSourceContent(name, files[name]);
|
236
|
-
}
|
237
|
-
}
|
238
309
|
}
|
239
310
|
delete options.format.ast;
|
240
311
|
delete options.format.code;
|
@@ -243,11 +314,21 @@ async function minify(files, options) {
|
|
243
314
|
toplevel.print(stream);
|
244
315
|
result.code = stream.get();
|
245
316
|
if (options.sourceMap) {
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
317
|
+
Object.defineProperty(result, "map", {
|
318
|
+
configurable: true,
|
319
|
+
enumerable: true,
|
320
|
+
get() {
|
321
|
+
const map = options.format.source_map.getEncoded();
|
322
|
+
return (result.map = options.sourceMap.asObject ? map : JSON.stringify(map));
|
323
|
+
},
|
324
|
+
set(value) {
|
325
|
+
Object.defineProperty(result, "map", {
|
326
|
+
value,
|
327
|
+
writable: true,
|
328
|
+
});
|
329
|
+
}
|
330
|
+
});
|
331
|
+
result.decoded_map = options.format.source_map.getDecoded();
|
251
332
|
if (options.sourceMap.url == "inline") {
|
252
333
|
var sourceMap = typeof result.map === "object" ? JSON.stringify(result.map) : result.map;
|
253
334
|
result.code += "\n//# sourceMappingURL=data:application/json;charset=utf-8;base64," + to_base64(sourceMap);
|