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.
@@ -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 = mkshallow({ value: "eq" });
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 = mkshallow({ "label.name": "eq" });
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 = mkshallow({
141
- init: "exist",
142
- condition: "exist",
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 = mkshallow({
157
- is_generator: "eq",
158
- async: "eq"
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 = mkshallow({
162
- is_array: "eq"
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 = mkshallow({
170
- "value": "eq"
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 = mkshallow({
180
- is_star: "eq"
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 = mkshallow({
184
- alternative: "exist"
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 = mkshallow({
192
- bcatch: "exist",
193
- bfinally: "exist"
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 = mkshallow({
197
- argname: "exist"
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 = mkshallow({
205
- value: "exist"
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 = mkshallow({
211
- imported_name: "exist",
212
- imported_names: "exist"
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 = mkshallow({
218
- exported_definition: "exist",
219
- exported_value: "exist",
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 = mkshallow({
234
- property: "eq"
235
- });
210
+ AST_Dot.prototype.shallow_cmp = function(other) {
211
+ return this.property === other.property;
212
+ };
236
213
 
237
- AST_DotHash.prototype.shallow_cmp = mkshallow({
238
- property: "eq"
239
- });
214
+ AST_DotHash.prototype.shallow_cmp = function(other) {
215
+ return this.property === other.property;
216
+ };
240
217
 
241
- AST_Unary.prototype.shallow_cmp = mkshallow({
242
- operator: "eq"
243
- });
218
+ AST_Unary.prototype.shallow_cmp = function(other) {
219
+ return this.operator === other.operator;
220
+ };
244
221
 
245
- AST_Binary.prototype.shallow_cmp = mkshallow({
246
- operator: "eq"
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 = mkshallow({
258
- key: "eq"
259
- });
234
+ AST_ObjectKeyVal.prototype.shallow_cmp = function(other) {
235
+ return this.key === other.key;
236
+ };
260
237
 
261
- AST_ObjectSetter.prototype.shallow_cmp = mkshallow({
262
- static: "eq"
263
- });
238
+ AST_ObjectSetter.prototype.shallow_cmp = function(other) {
239
+ return this.static === other.static;
240
+ };
264
241
 
265
- AST_ObjectGetter.prototype.shallow_cmp = mkshallow({
266
- static: "eq"
267
- });
242
+ AST_ObjectGetter.prototype.shallow_cmp = function(other) {
243
+ return this.static === other.static;
244
+ };
268
245
 
269
- AST_ConciseMethod.prototype.shallow_cmp = mkshallow({
270
- static: "eq",
271
- is_generator: "eq",
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 = mkshallow({
276
- name: "exist",
277
- extends: "exist",
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 = mkshallow({
281
- static: "eq"
282
- });
254
+ AST_ClassProperty.prototype.shallow_cmp = function(other) {
255
+ return this.static === other.static;
256
+ };
283
257
 
284
- AST_Symbol.prototype.shallow_cmp = mkshallow({
285
- name: "eq"
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 = mkshallow({
295
- value: "eq"
296
- });
268
+ AST_String.prototype.shallow_cmp = function(other) {
269
+ return this.value === other.value;
270
+ };
297
271
 
298
- AST_Number.prototype.shallow_cmp = mkshallow({
299
- value: "eq"
300
- });
272
+ AST_Number.prototype.shallow_cmp = function(other) {
273
+ return this.value === other.value;
274
+ };
301
275
 
302
- AST_BigInt.prototype.shallow_cmp = mkshallow({
303
- value: "eq"
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
- async function minify(files, options) {
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
- if(options.sourceMap.asObject) {
247
- result.map = options.format.source_map.get().toJSON();
248
- } else {
249
- result.map = options.format.source_map.toString();
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);