terser 5.22.0 → 5.24.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 +7 -0
- package/dist/bundle.min.js +85 -34
- package/lib/compress/index.js +8 -2
- package/lib/compress/inline.js +29 -4
- package/lib/output.js +47 -27
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## v5.24.0
|
4
|
+
- Improve formatting performance in V8 by keeping a small work string and a large output string
|
5
|
+
|
6
|
+
## v5.23.0
|
7
|
+
- When top_retain will keep a variable assignment around, inline the assignee when it's shorter than the name (#1434)
|
8
|
+
- Remove empty class `static {}` blocks.
|
9
|
+
|
3
10
|
## v5.22.0
|
4
11
|
- Do not `unsafe`ly shorten expressions like a?.toString() when they're conditional.
|
5
12
|
- Avoid running drop_unused in nodes that aren't scopes. Fixes a rare crash.
|
package/dist/bundle.min.js
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@jridgewell/source-map')) :
|
3
3
|
typeof define === 'function' && define.amd ? define(['exports', '@jridgewell/source-map'], factory) :
|
4
4
|
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.Terser = {}, global.sourceMap));
|
5
|
-
}(this, (function (exports, sourceMap) { 'use strict';
|
5
|
+
})(this, (function (exports, sourceMap) { 'use strict';
|
6
6
|
|
7
7
|
/***********************************************************************
|
8
8
|
|
@@ -8928,7 +8928,6 @@ function left_is_object(node) {
|
|
8928
8928
|
|
8929
8929
|
***********************************************************************/
|
8930
8930
|
|
8931
|
-
const EXPECT_DIRECTIVE = /^$|[;{][\s\n]*$/;
|
8932
8931
|
const CODE_LINE_BREAK = 10;
|
8933
8932
|
const CODE_SPACE = 32;
|
8934
8933
|
|
@@ -8942,6 +8941,7 @@ function is_some_comments(comment) {
|
|
8942
8941
|
);
|
8943
8942
|
}
|
8944
8943
|
|
8944
|
+
const ROPE_COMMIT_WHEN = 8 * 1000;
|
8945
8945
|
class Rope {
|
8946
8946
|
constructor() {
|
8947
8947
|
this.committed = "";
|
@@ -8949,7 +8949,13 @@ class Rope {
|
|
8949
8949
|
}
|
8950
8950
|
|
8951
8951
|
append(str) {
|
8952
|
-
this.current
|
8952
|
+
/** When `this.current` is too long, commit it. */
|
8953
|
+
if (this.current.length > ROPE_COMMIT_WHEN) {
|
8954
|
+
this.committed += this.current + str;
|
8955
|
+
this.current = "";
|
8956
|
+
} else {
|
8957
|
+
this.current += str;
|
8958
|
+
}
|
8953
8959
|
}
|
8954
8960
|
|
8955
8961
|
insertAt(char, index) {
|
@@ -8971,14 +8977,45 @@ class Rope {
|
|
8971
8977
|
return this.current[index - committed.length];
|
8972
8978
|
}
|
8973
8979
|
|
8974
|
-
|
8975
|
-
|
8980
|
+
charCodeAt(index) {
|
8981
|
+
const { committed } = this;
|
8982
|
+
if (index < committed.length) return committed.charCodeAt(index);
|
8983
|
+
return this.current.charCodeAt(index - committed.length);
|
8976
8984
|
}
|
8977
8985
|
|
8978
8986
|
length() {
|
8979
8987
|
return this.committed.length + this.current.length;
|
8980
8988
|
}
|
8981
8989
|
|
8990
|
+
expectDirective() {
|
8991
|
+
// /^$|[;{][\s\n]*$/
|
8992
|
+
|
8993
|
+
let ch, n = this.length();
|
8994
|
+
|
8995
|
+
if (n <= 0) return true;
|
8996
|
+
|
8997
|
+
// Skip N whitespace from the end
|
8998
|
+
while (
|
8999
|
+
(ch = this.charCodeAt(--n))
|
9000
|
+
&& (ch == CODE_SPACE || ch == CODE_LINE_BREAK)
|
9001
|
+
);
|
9002
|
+
|
9003
|
+
// either ";", or "{", or the string ended
|
9004
|
+
return !ch || ch === 59 || ch === 123;
|
9005
|
+
}
|
9006
|
+
|
9007
|
+
hasNLB() {
|
9008
|
+
let n = this.length() - 1;
|
9009
|
+
while (n >= 0) {
|
9010
|
+
const code = this.charCodeAt(n--);
|
9011
|
+
|
9012
|
+
if (code === CODE_LINE_BREAK) return true;
|
9013
|
+
if (code !== CODE_SPACE) return false;
|
9014
|
+
}
|
9015
|
+
return true;
|
9016
|
+
}
|
9017
|
+
|
9018
|
+
|
8982
9019
|
toString() {
|
8983
9020
|
return this.committed + this.current;
|
8984
9021
|
}
|
@@ -9184,9 +9221,9 @@ function OutputStream(options) {
|
|
9184
9221
|
if (current_col > options.max_line_len) {
|
9185
9222
|
if (might_add_newline) {
|
9186
9223
|
OUTPUT.insertAt("\n", might_add_newline);
|
9187
|
-
const
|
9224
|
+
const len_after_newline = OUTPUT.length() - might_add_newline - 1;
|
9188
9225
|
if (mappings) {
|
9189
|
-
var delta =
|
9226
|
+
var delta = len_after_newline - current_col;
|
9190
9227
|
mappings.forEach(function(mapping) {
|
9191
9228
|
mapping.line++;
|
9192
9229
|
mapping.col += delta;
|
@@ -9194,7 +9231,7 @@ function OutputStream(options) {
|
|
9194
9231
|
}
|
9195
9232
|
current_line++;
|
9196
9233
|
current_pos++;
|
9197
|
-
current_col =
|
9234
|
+
current_col = len_after_newline;
|
9198
9235
|
}
|
9199
9236
|
}
|
9200
9237
|
if (might_add_newline) {
|
@@ -9393,23 +9430,6 @@ function OutputStream(options) {
|
|
9393
9430
|
return OUTPUT.toString();
|
9394
9431
|
}
|
9395
9432
|
|
9396
|
-
function has_nlb() {
|
9397
|
-
const output = OUTPUT.toString();
|
9398
|
-
let n = output.length - 1;
|
9399
|
-
while (n >= 0) {
|
9400
|
-
const code = output.charCodeAt(n);
|
9401
|
-
if (code === CODE_LINE_BREAK) {
|
9402
|
-
return true;
|
9403
|
-
}
|
9404
|
-
|
9405
|
-
if (code !== CODE_SPACE) {
|
9406
|
-
return false;
|
9407
|
-
}
|
9408
|
-
n--;
|
9409
|
-
}
|
9410
|
-
return true;
|
9411
|
-
}
|
9412
|
-
|
9413
9433
|
function filter_comment(comment) {
|
9414
9434
|
if (!options.preserve_annotations) {
|
9415
9435
|
comment = comment.replace(r_annotation, " ");
|
@@ -9490,7 +9510,7 @@ function OutputStream(options) {
|
|
9490
9510
|
|
9491
9511
|
comments = comments.filter(comment_filter, node).filter(c => !printed_comments.has(c));
|
9492
9512
|
if (comments.length == 0) return;
|
9493
|
-
var last_nlb =
|
9513
|
+
var last_nlb = OUTPUT.hasNLB();
|
9494
9514
|
comments.forEach(function(c, i) {
|
9495
9515
|
printed_comments.add(c);
|
9496
9516
|
if (!last_nlb) {
|
@@ -9548,7 +9568,7 @@ function OutputStream(options) {
|
|
9548
9568
|
print("\n");
|
9549
9569
|
indent();
|
9550
9570
|
need_newline_indented = false;
|
9551
|
-
} else if (c.nlb && (i > 0 || !
|
9571
|
+
} else if (c.nlb && (i > 0 || !OUTPUT.hasNLB())) {
|
9552
9572
|
print("\n");
|
9553
9573
|
indent();
|
9554
9574
|
} else if (i > 0 || !tail) {
|
@@ -9610,7 +9630,7 @@ function OutputStream(options) {
|
|
9610
9630
|
var encoded = encode_string(str, quote);
|
9611
9631
|
if (escape_directive === true && !encoded.includes("\\")) {
|
9612
9632
|
// Insert semicolons to break directive prologue
|
9613
|
-
if (!
|
9633
|
+
if (!OUTPUT.expectDirective()) {
|
9614
9634
|
force_semicolon();
|
9615
9635
|
}
|
9616
9636
|
force_semicolon();
|
@@ -17696,18 +17716,43 @@ function scope_encloses_variables_in_this_scope(scope, pulled_scope) {
|
|
17696
17716
|
return false;
|
17697
17717
|
}
|
17698
17718
|
|
17719
|
+
/**
|
17720
|
+
* An extra check function for `top_retain` option, compare the length of const identifier
|
17721
|
+
* and init value length and return true if init value is longer than identifier. for example:
|
17722
|
+
* ```
|
17723
|
+
* // top_retain: ["example"]
|
17724
|
+
* const example = 100
|
17725
|
+
* ```
|
17726
|
+
* it will return false because length of "100" is short than identifier "example".
|
17727
|
+
*/
|
17728
|
+
function is_const_symbol_short_than_init_value(def, fixed_value) {
|
17729
|
+
if (def.orig.length === 1 && fixed_value) {
|
17730
|
+
const init_value_length = fixed_value.size();
|
17731
|
+
const identifer_length = def.name.length;
|
17732
|
+
return init_value_length > identifer_length;
|
17733
|
+
}
|
17734
|
+
return true;
|
17735
|
+
}
|
17736
|
+
|
17699
17737
|
function inline_into_symbolref(self, compressor) {
|
17700
17738
|
const parent = compressor.parent();
|
17701
|
-
|
17702
17739
|
const def = self.definition();
|
17703
17740
|
const nearest_scope = compressor.find_scope();
|
17704
|
-
|
17741
|
+
let fixed = self.fixed_value();
|
17742
|
+
if (
|
17743
|
+
compressor.top_retain &&
|
17744
|
+
def.global &&
|
17745
|
+
compressor.top_retain(def) &&
|
17746
|
+
// when identifier is in top_retain option dose not mean we can always inline it.
|
17747
|
+
// if identifier name is longer then init value, we can replace it.
|
17748
|
+
is_const_symbol_short_than_init_value(def, fixed)
|
17749
|
+
) {
|
17750
|
+
// keep it
|
17705
17751
|
def.fixed = false;
|
17706
17752
|
def.single_use = false;
|
17707
17753
|
return self;
|
17708
17754
|
}
|
17709
17755
|
|
17710
|
-
let fixed = self.fixed_value();
|
17711
17756
|
let single_use = def.single_use
|
17712
17757
|
&& !(parent instanceof AST_Call
|
17713
17758
|
&& (parent.is_callee_pure(compressor))
|
@@ -21643,8 +21688,14 @@ def_optimize(AST_Function, function(self, compressor) {
|
|
21643
21688
|
});
|
21644
21689
|
|
21645
21690
|
def_optimize(AST_Class, function(self) {
|
21646
|
-
|
21647
|
-
|
21691
|
+
for (let i = 0; i < self.properties.length; i++) {
|
21692
|
+
const prop = self.properties[i];
|
21693
|
+
if (prop instanceof AST_ClassStaticBlock && prop.body.length == 0) {
|
21694
|
+
self.properties.splice(i, 1);
|
21695
|
+
i--;
|
21696
|
+
}
|
21697
|
+
}
|
21698
|
+
|
21648
21699
|
return self;
|
21649
21700
|
});
|
21650
21701
|
|
@@ -31264,4 +31315,4 @@ exports._default_options = _default_options;
|
|
31264
31315
|
exports._run_cli = run_cli;
|
31265
31316
|
exports.minify = minify;
|
31266
31317
|
|
31267
|
-
}))
|
31318
|
+
}));
|
package/lib/compress/index.js
CHANGED
@@ -3549,8 +3549,14 @@ def_optimize(AST_Function, function(self, compressor) {
|
|
3549
3549
|
});
|
3550
3550
|
|
3551
3551
|
def_optimize(AST_Class, function(self) {
|
3552
|
-
|
3553
|
-
|
3552
|
+
for (let i = 0; i < self.properties.length; i++) {
|
3553
|
+
const prop = self.properties[i];
|
3554
|
+
if (prop instanceof AST_ClassStaticBlock && prop.body.length == 0) {
|
3555
|
+
self.properties.splice(i, 1);
|
3556
|
+
i--;
|
3557
|
+
}
|
3558
|
+
}
|
3559
|
+
|
3554
3560
|
return self;
|
3555
3561
|
});
|
3556
3562
|
|
package/lib/compress/inline.js
CHANGED
@@ -84,7 +84,7 @@ import {
|
|
84
84
|
|
85
85
|
_INLINE,
|
86
86
|
_NOINLINE,
|
87
|
-
_PURE
|
87
|
+
_PURE,
|
88
88
|
} from "../ast.js";
|
89
89
|
import { make_node, has_annotation } from "../utils/index.js";
|
90
90
|
import "../size.js";
|
@@ -148,18 +148,43 @@ function scope_encloses_variables_in_this_scope(scope, pulled_scope) {
|
|
148
148
|
return false;
|
149
149
|
}
|
150
150
|
|
151
|
+
/**
|
152
|
+
* An extra check function for `top_retain` option, compare the length of const identifier
|
153
|
+
* and init value length and return true if init value is longer than identifier. for example:
|
154
|
+
* ```
|
155
|
+
* // top_retain: ["example"]
|
156
|
+
* const example = 100
|
157
|
+
* ```
|
158
|
+
* it will return false because length of "100" is short than identifier "example".
|
159
|
+
*/
|
160
|
+
function is_const_symbol_short_than_init_value(def, fixed_value) {
|
161
|
+
if (def.orig.length === 1 && fixed_value) {
|
162
|
+
const init_value_length = fixed_value.size();
|
163
|
+
const identifer_length = def.name.length;
|
164
|
+
return init_value_length > identifer_length;
|
165
|
+
}
|
166
|
+
return true;
|
167
|
+
}
|
168
|
+
|
151
169
|
export function inline_into_symbolref(self, compressor) {
|
152
170
|
const parent = compressor.parent();
|
153
|
-
|
154
171
|
const def = self.definition();
|
155
172
|
const nearest_scope = compressor.find_scope();
|
156
|
-
|
173
|
+
let fixed = self.fixed_value();
|
174
|
+
if (
|
175
|
+
compressor.top_retain &&
|
176
|
+
def.global &&
|
177
|
+
compressor.top_retain(def) &&
|
178
|
+
// when identifier is in top_retain option dose not mean we can always inline it.
|
179
|
+
// if identifier name is longer then init value, we can replace it.
|
180
|
+
is_const_symbol_short_than_init_value(def, fixed)
|
181
|
+
) {
|
182
|
+
// keep it
|
157
183
|
def.fixed = false;
|
158
184
|
def.single_use = false;
|
159
185
|
return self;
|
160
186
|
}
|
161
187
|
|
162
|
-
let fixed = self.fixed_value();
|
163
188
|
let single_use = def.single_use
|
164
189
|
&& !(parent instanceof AST_Call
|
165
190
|
&& (parent.is_callee_pure(compressor))
|
package/lib/output.js
CHANGED
@@ -166,7 +166,6 @@ import {
|
|
166
166
|
ALL_RESERVED_WORDS,
|
167
167
|
} from "./parse.js";
|
168
168
|
|
169
|
-
const EXPECT_DIRECTIVE = /^$|[;{][\s\n]*$/;
|
170
169
|
const CODE_LINE_BREAK = 10;
|
171
170
|
const CODE_SPACE = 32;
|
172
171
|
|
@@ -180,6 +179,7 @@ function is_some_comments(comment) {
|
|
180
179
|
);
|
181
180
|
}
|
182
181
|
|
182
|
+
const ROPE_COMMIT_WHEN = 8 * 1000;
|
183
183
|
class Rope {
|
184
184
|
constructor() {
|
185
185
|
this.committed = "";
|
@@ -187,7 +187,13 @@ class Rope {
|
|
187
187
|
}
|
188
188
|
|
189
189
|
append(str) {
|
190
|
-
this.current
|
190
|
+
/** When `this.current` is too long, commit it. */
|
191
|
+
if (this.current.length > ROPE_COMMIT_WHEN) {
|
192
|
+
this.committed += this.current + str;
|
193
|
+
this.current = "";
|
194
|
+
} else {
|
195
|
+
this.current += str;
|
196
|
+
}
|
191
197
|
}
|
192
198
|
|
193
199
|
insertAt(char, index) {
|
@@ -209,14 +215,45 @@ class Rope {
|
|
209
215
|
return this.current[index - committed.length];
|
210
216
|
}
|
211
217
|
|
212
|
-
|
213
|
-
|
218
|
+
charCodeAt(index) {
|
219
|
+
const { committed } = this;
|
220
|
+
if (index < committed.length) return committed.charCodeAt(index);
|
221
|
+
return this.current.charCodeAt(index - committed.length);
|
214
222
|
}
|
215
223
|
|
216
224
|
length() {
|
217
225
|
return this.committed.length + this.current.length;
|
218
226
|
}
|
219
227
|
|
228
|
+
expectDirective() {
|
229
|
+
// /^$|[;{][\s\n]*$/
|
230
|
+
|
231
|
+
let ch, n = this.length();
|
232
|
+
|
233
|
+
if (n <= 0) return true;
|
234
|
+
|
235
|
+
// Skip N whitespace from the end
|
236
|
+
while (
|
237
|
+
(ch = this.charCodeAt(--n))
|
238
|
+
&& (ch == CODE_SPACE || ch == CODE_LINE_BREAK)
|
239
|
+
);
|
240
|
+
|
241
|
+
// either ";", or "{", or the string ended
|
242
|
+
return !ch || ch === 59 || ch === 123;
|
243
|
+
}
|
244
|
+
|
245
|
+
hasNLB() {
|
246
|
+
let n = this.length() - 1;
|
247
|
+
while (n >= 0) {
|
248
|
+
const code = this.charCodeAt(n--);
|
249
|
+
|
250
|
+
if (code === CODE_LINE_BREAK) return true;
|
251
|
+
if (code !== CODE_SPACE) return false;
|
252
|
+
}
|
253
|
+
return true;
|
254
|
+
}
|
255
|
+
|
256
|
+
|
220
257
|
toString() {
|
221
258
|
return this.committed + this.current;
|
222
259
|
}
|
@@ -422,9 +459,9 @@ function OutputStream(options) {
|
|
422
459
|
if (current_col > options.max_line_len) {
|
423
460
|
if (might_add_newline) {
|
424
461
|
OUTPUT.insertAt("\n", might_add_newline);
|
425
|
-
const
|
462
|
+
const len_after_newline = OUTPUT.length() - might_add_newline - 1;
|
426
463
|
if (mappings) {
|
427
|
-
var delta =
|
464
|
+
var delta = len_after_newline - current_col;
|
428
465
|
mappings.forEach(function(mapping) {
|
429
466
|
mapping.line++;
|
430
467
|
mapping.col += delta;
|
@@ -432,7 +469,7 @@ function OutputStream(options) {
|
|
432
469
|
}
|
433
470
|
current_line++;
|
434
471
|
current_pos++;
|
435
|
-
current_col =
|
472
|
+
current_col = len_after_newline;
|
436
473
|
}
|
437
474
|
}
|
438
475
|
if (might_add_newline) {
|
@@ -631,23 +668,6 @@ function OutputStream(options) {
|
|
631
668
|
return OUTPUT.toString();
|
632
669
|
}
|
633
670
|
|
634
|
-
function has_nlb() {
|
635
|
-
const output = OUTPUT.toString();
|
636
|
-
let n = output.length - 1;
|
637
|
-
while (n >= 0) {
|
638
|
-
const code = output.charCodeAt(n);
|
639
|
-
if (code === CODE_LINE_BREAK) {
|
640
|
-
return true;
|
641
|
-
}
|
642
|
-
|
643
|
-
if (code !== CODE_SPACE) {
|
644
|
-
return false;
|
645
|
-
}
|
646
|
-
n--;
|
647
|
-
}
|
648
|
-
return true;
|
649
|
-
}
|
650
|
-
|
651
671
|
function filter_comment(comment) {
|
652
672
|
if (!options.preserve_annotations) {
|
653
673
|
comment = comment.replace(r_annotation, " ");
|
@@ -728,7 +748,7 @@ function OutputStream(options) {
|
|
728
748
|
|
729
749
|
comments = comments.filter(comment_filter, node).filter(c => !printed_comments.has(c));
|
730
750
|
if (comments.length == 0) return;
|
731
|
-
var last_nlb =
|
751
|
+
var last_nlb = OUTPUT.hasNLB();
|
732
752
|
comments.forEach(function(c, i) {
|
733
753
|
printed_comments.add(c);
|
734
754
|
if (!last_nlb) {
|
@@ -786,7 +806,7 @@ function OutputStream(options) {
|
|
786
806
|
print("\n");
|
787
807
|
indent();
|
788
808
|
need_newline_indented = false;
|
789
|
-
} else if (c.nlb && (i > 0 || !
|
809
|
+
} else if (c.nlb && (i > 0 || !OUTPUT.hasNLB())) {
|
790
810
|
print("\n");
|
791
811
|
indent();
|
792
812
|
} else if (i > 0 || !tail) {
|
@@ -848,7 +868,7 @@ function OutputStream(options) {
|
|
848
868
|
var encoded = encode_string(str, quote);
|
849
869
|
if (escape_directive === true && !encoded.includes("\\")) {
|
850
870
|
// Insert semicolons to break directive prologue
|
851
|
-
if (!
|
871
|
+
if (!OUTPUT.expectDirective()) {
|
852
872
|
force_semicolon();
|
853
873
|
}
|
854
874
|
force_semicolon();
|