terser 5.10.0 → 5.12.1
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 +15 -0
- package/README.md +30 -8
- package/dist/bundle.min.js +90 -15
- package/lib/cli.js +13 -9
- package/lib/minify.js +49 -1
- package/lib/output.js +6 -5
- package/lib/scope.js +22 -0
- package/package.json +5 -10
- package/bin/terser.mjs +0 -19
package/CHANGELOG.md
CHANGED
@@ -1,5 +1,20 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## v5.12.1
|
4
|
+
|
5
|
+
- Fixed an issue with function definitions inside blocks (#1155)
|
6
|
+
- Fixed parens of `new` in some situations (closes #1159)
|
7
|
+
|
8
|
+
## v5.12.0
|
9
|
+
|
10
|
+
- `TERSER_DEBUG_DIR` environment variable
|
11
|
+
- @copyright comments are now preserved with the comments="some" option (#1153)
|
12
|
+
|
13
|
+
## v5.11.0
|
14
|
+
|
15
|
+
- Unicode code point escapes (`\u{abcde}`) are not emitted inside RegExp literals anymore (#1147)
|
16
|
+
- acorn is now a regular dependency
|
17
|
+
|
3
18
|
## v5.10.0
|
4
19
|
|
5
20
|
- Massive optimization to max_line_len (#1109)
|
package/README.md
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
[![Travis Build][travis-image]][travis-url]
|
6
6
|
[![Opencollective financial contributors][opencollective-contributors]][opencollective-url]
|
7
7
|
|
8
|
-
A JavaScript
|
8
|
+
A JavaScript mangler/compressor toolkit for ES6+.
|
9
9
|
|
10
10
|
*note*: You can support this project on patreon: <a target="_blank" rel="nofollow" href="https://www.patreon.com/fabiosantoscode"><img src="https://c5.patreon.com/external/logo/become_a_patron_button@2x.png" alt="patron" width="100px" height="auto"></a>. Check out [PATRONS.md](https://github.com/terser/terser/blob/master/PATRONS.md) for our first-tier patrons.
|
11
11
|
|
@@ -60,6 +60,12 @@ in sequence and apply any compression options. The files are parsed in the
|
|
60
60
|
same global scope, that is, a reference from a file to some
|
61
61
|
variable/function declared in another file will be matched properly.
|
62
62
|
|
63
|
+
Command line arguments that take options (like --parse, --compress, --mangle and
|
64
|
+
--format) can take in a comma-separated list of default option overrides. For
|
65
|
+
instance:
|
66
|
+
|
67
|
+
terser input.js --compress ecma=2015,computed_props=false
|
68
|
+
|
63
69
|
If no input file is specified, Terser will read from STDIN.
|
64
70
|
|
65
71
|
If you wish to pass your options before the input files, separate the two with
|
@@ -121,8 +127,8 @@ a double dash to prevent input files being used as option arguments:
|
|
121
127
|
as JSON to STDOUT respectively.
|
122
128
|
--comments [filter] Preserve copyright comments in the output. By
|
123
129
|
default this works like Google Closure, keeping
|
124
|
-
JSDoc-style comments that contain "@license"
|
125
|
-
"
|
130
|
+
JSDoc-style comments that contain e.g. "@license",
|
131
|
+
or start with "!". You can optionally pass one of the
|
126
132
|
following arguments to this flag:
|
127
133
|
- "all" to keep all comments
|
128
134
|
- `false` to omit comments in the output
|
@@ -983,8 +989,8 @@ as "output options".
|
|
983
989
|
statement.
|
984
990
|
|
985
991
|
- `comments` (default `"some"`) -- by default it keeps JSDoc-style comments
|
986
|
-
that contain "@license", "@preserve" or start with `!`, pass `true`
|
987
|
-
`"all"` to preserve all comments, `false` to omit comments in the output,
|
992
|
+
that contain "@license", "@copyright", "@preserve" or start with `!`, pass `true`
|
993
|
+
or `"all"` to preserve all comments, `false` to omit comments in the output,
|
988
994
|
a regular expression string (e.g. `/^!/`) or a function.
|
989
995
|
|
990
996
|
- `ecma` (default `5`) -- set desired EcmaScript standard version for output.
|
@@ -1056,9 +1062,9 @@ as "output options".
|
|
1056
1062
|
### Keeping copyright notices or other comments
|
1057
1063
|
|
1058
1064
|
You can pass `--comments` to retain certain comments in the output. By
|
1059
|
-
default it will keep JSDoc-style comments that
|
1060
|
-
"@license" or "@cc_on" (conditional compilation for IE).
|
1061
|
-
`--comments all` to keep all the comments, or a valid JavaScript regexp to
|
1065
|
+
default it will keep comments starting with "!" and JSDoc-style comments that
|
1066
|
+
contain "@preserve", "@copyright", "@license" or "@cc_on" (conditional compilation for IE).
|
1067
|
+
You can pass `--comments all` to keep all the comments, or a valid JavaScript regexp to
|
1062
1068
|
keep only comments that match this regexp. For example `--comments /^!/`
|
1063
1069
|
will keep comments like `/*! Copyright Notice */`.
|
1064
1070
|
|
@@ -1312,6 +1318,22 @@ $ yarn
|
|
1312
1318
|
|
1313
1319
|
In the terser CLI we use [source-map-support](https://npmjs.com/source-map-support) to produce good error stacks. In your own app, you're expected to enable source-map-support (read their docs) to have nice stack traces that will help you write good issues.
|
1314
1320
|
|
1321
|
+
## Obtaining the source code given to Terser
|
1322
|
+
|
1323
|
+
Because users often don't control the call to `await minify()` or its arguments, Terser provides a `TERSER_DEBUG_DIR` environment variable to make terser output some debug logs. If you're using a bundler or a project that includes a bundler and are not sure what went wrong with your code, pass that variable like so:
|
1324
|
+
|
1325
|
+
```
|
1326
|
+
$ TERSER_DEBUG_DIR=/path/to/logs command-that-uses-terser
|
1327
|
+
$ ls /path/to/logs
|
1328
|
+
terser-debug-123456.log
|
1329
|
+
```
|
1330
|
+
|
1331
|
+
If you're not sure how to set an environment variable on your shell (the above example works in bash), you can try using cross-env:
|
1332
|
+
|
1333
|
+
```
|
1334
|
+
> npx cross-env TERSER_DEBUG_DIR=/path/to/logs command-that-uses-terser
|
1335
|
+
```
|
1336
|
+
|
1315
1337
|
# README.md Patrons:
|
1316
1338
|
|
1317
1339
|
*note*: You can support this project on patreon: <a target="_blank" rel="nofollow" href="https://www.patreon.com/fabiosantoscode"><img src="https://c5.patreon.com/external/logo/become_a_patron_button@2x.png" alt="patron" width="100px" height="auto"></a>. Check out [PATRONS.md](https://github.com/terser/terser/blob/master/PATRONS.md) for our first-tier patrons.
|
package/dist/bundle.min.js
CHANGED
@@ -6975,7 +6975,7 @@ function is_some_comments(comment) {
|
|
6975
6975
|
// multiline comment
|
6976
6976
|
return (
|
6977
6977
|
(comment.type === "comment2" || comment.type === "comment1")
|
6978
|
-
&& /@preserve|@lic|@cc_on|^\**!/i.test(comment.value)
|
6978
|
+
&& /@preserve|@copyright|@lic|@cc_on|^\**!/i.test(comment.value)
|
6979
6979
|
);
|
6980
6980
|
}
|
6981
6981
|
|
@@ -7088,8 +7088,8 @@ function OutputStream(options) {
|
|
7088
7088
|
var OUTPUT = new Rope();
|
7089
7089
|
let printed_comments = new Set();
|
7090
7090
|
|
7091
|
-
var to_utf8 = options.ascii_only ? function(str, identifier) {
|
7092
|
-
if (options.ecma >= 2015 && !options.safari10) {
|
7091
|
+
var to_utf8 = options.ascii_only ? function(str, identifier = false, regexp = false) {
|
7092
|
+
if (options.ecma >= 2015 && !options.safari10 && !regexp) {
|
7093
7093
|
str = str.replace(/[\ud800-\udbff][\udc00-\udfff]/g, function(ch) {
|
7094
7094
|
var code = get_full_char_code(ch, 0).toString(16);
|
7095
7095
|
return "\\u{" + code + "}";
|
@@ -7901,7 +7901,8 @@ function OutputStream(options) {
|
|
7901
7901
|
var p = output.parent();
|
7902
7902
|
if (this.args.length === 0
|
7903
7903
|
&& (p instanceof AST_PropAccess // (new Date).getTime(), (new Date)["getTime"]()
|
7904
|
-
|| p instanceof AST_Call && p.expression === this
|
7904
|
+
|| p instanceof AST_Call && p.expression === this
|
7905
|
+
|| p instanceof AST_PrefixedTemplateString && p.prefix === this)) // (new foo)(bar)
|
7905
7906
|
return true;
|
7906
7907
|
});
|
7907
7908
|
|
@@ -9016,7 +9017,7 @@ function OutputStream(options) {
|
|
9016
9017
|
flags = flags ? sort_regexp_flags(flags) : "";
|
9017
9018
|
source = source.replace(r_slash_script, slash_script_replace);
|
9018
9019
|
|
9019
|
-
output.print(output.to_utf8(`/${source}/${flags}
|
9020
|
+
output.print(output.to_utf8(`/${source}/${flags}`, false, true));
|
9020
9021
|
|
9021
9022
|
const parent = output.parent();
|
9022
9023
|
if (
|
@@ -9440,6 +9441,11 @@ const MASK_EXPORT_WANT_MANGLE = 1 << 1;
|
|
9440
9441
|
|
9441
9442
|
let function_defs = null;
|
9442
9443
|
let unmangleable_names = null;
|
9444
|
+
/**
|
9445
|
+
* When defined, there is a function declaration somewhere that's inside of a block.
|
9446
|
+
* See https://tc39.es/ecma262/multipage/additional-ecmascript-features-for-web-browsers.html#sec-block-level-function-declarations-web-legacy-compatibility-semantics
|
9447
|
+
*/
|
9448
|
+
let scopes_with_block_defuns = null;
|
9443
9449
|
|
9444
9450
|
class SymbolDef {
|
9445
9451
|
constructor(scope, orig, init) {
|
@@ -9990,6 +9996,15 @@ AST_Scope.DEFMETHOD("def_variable", function(symbol, init) {
|
|
9990
9996
|
});
|
9991
9997
|
|
9992
9998
|
function next_mangled(scope, options) {
|
9999
|
+
let defun_scope;
|
10000
|
+
if (
|
10001
|
+
scopes_with_block_defuns
|
10002
|
+
&& (defun_scope = scope.get_defun_scope())
|
10003
|
+
&& scopes_with_block_defuns.has(defun_scope)
|
10004
|
+
) {
|
10005
|
+
scope = defun_scope;
|
10006
|
+
}
|
10007
|
+
|
9993
10008
|
var ext = scope.enclosed;
|
9994
10009
|
var nth_identifier = options.nth_identifier;
|
9995
10010
|
out: while (true) {
|
@@ -10124,6 +10139,13 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
|
|
10124
10139
|
lname = save_nesting;
|
10125
10140
|
return true; // don't descend again in TreeWalker
|
10126
10141
|
}
|
10142
|
+
if (
|
10143
|
+
node instanceof AST_Defun
|
10144
|
+
&& !(tw.parent() instanceof AST_Scope)
|
10145
|
+
) {
|
10146
|
+
scopes_with_block_defuns = scopes_with_block_defuns || new Set();
|
10147
|
+
scopes_with_block_defuns.add(node.parent_scope.get_defun_scope());
|
10148
|
+
}
|
10127
10149
|
if (node instanceof AST_Scope) {
|
10128
10150
|
node.variables.forEach(collect);
|
10129
10151
|
return;
|
@@ -10172,6 +10194,7 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
|
|
10172
10194
|
|
10173
10195
|
function_defs = null;
|
10174
10196
|
unmangleable_names = null;
|
10197
|
+
scopes_with_block_defuns = null;
|
10175
10198
|
|
10176
10199
|
function collect(symbol) {
|
10177
10200
|
if (symbol.export & MASK_EXPORT_DONT_MANGLE) {
|
@@ -27555,7 +27578,54 @@ function cache_to_json(cache) {
|
|
27555
27578
|
};
|
27556
27579
|
}
|
27557
27580
|
|
27558
|
-
|
27581
|
+
function log_input(files, options, fs, debug_folder) {
|
27582
|
+
if (!(fs && fs.writeFileSync && fs.mkdirSync)) {
|
27583
|
+
return;
|
27584
|
+
}
|
27585
|
+
|
27586
|
+
try {
|
27587
|
+
fs.mkdirSync(debug_folder);
|
27588
|
+
} catch (e) {
|
27589
|
+
if (e.code !== "EEXIST") throw e;
|
27590
|
+
}
|
27591
|
+
|
27592
|
+
const log_path = `${debug_folder}/terser-debug-${(Math.random() * 9999999) | 0}.log`;
|
27593
|
+
|
27594
|
+
options = options || {};
|
27595
|
+
|
27596
|
+
const options_str = JSON.stringify(options, (_key, thing) => {
|
27597
|
+
if (typeof thing === "function") return "[Function " + thing.toString() + "]";
|
27598
|
+
if (thing instanceof RegExp) return "[RegExp " + thing.toString() + "]";
|
27599
|
+
return thing;
|
27600
|
+
}, 4);
|
27601
|
+
|
27602
|
+
const files_str = (file) => {
|
27603
|
+
if (typeof file === "object" && options.parse && options.parse.spidermonkey) {
|
27604
|
+
return JSON.stringify(file, null, 2);
|
27605
|
+
} else if (typeof file === "object") {
|
27606
|
+
return Object.keys(file)
|
27607
|
+
.map((key) => key + ": " + files_str(file[key]))
|
27608
|
+
.join("\n\n");
|
27609
|
+
} else if (typeof file === "string") {
|
27610
|
+
return "```\n" + file + "\n```";
|
27611
|
+
} else {
|
27612
|
+
return file; // What do?
|
27613
|
+
}
|
27614
|
+
};
|
27615
|
+
|
27616
|
+
fs.writeFileSync(log_path, "Options: \n" + options_str + "\n\nInput files:\n\n" + files_str(files) + "\n");
|
27617
|
+
}
|
27618
|
+
|
27619
|
+
async function minify(files, options, _fs_module) {
|
27620
|
+
if (
|
27621
|
+
_fs_module
|
27622
|
+
&& typeof process === "object"
|
27623
|
+
&& process.env
|
27624
|
+
&& typeof process.env.TERSER_DEBUG_DIR === "string"
|
27625
|
+
) {
|
27626
|
+
log_input(files, options, _fs_module, process.env.TERSER_DEBUG_DIR);
|
27627
|
+
}
|
27628
|
+
|
27559
27629
|
options = defaults(options, {
|
27560
27630
|
compress: {},
|
27561
27631
|
ecma: undefined,
|
@@ -27578,6 +27648,7 @@ async function minify(files, options) {
|
|
27578
27648
|
warnings: false,
|
27579
27649
|
wrap: false,
|
27580
27650
|
}, true);
|
27651
|
+
|
27581
27652
|
var timings = options.timings && {
|
27582
27653
|
start: Date.now()
|
27583
27654
|
};
|
@@ -27979,7 +28050,7 @@ async function run_cli({ program, packageJson, fs, path }) {
|
|
27979
28050
|
|
27980
28051
|
let result;
|
27981
28052
|
try {
|
27982
|
-
result = await minify(files, options);
|
28053
|
+
result = await minify(files, options, fs);
|
27983
28054
|
} catch (ex) {
|
27984
28055
|
if (ex.name == "SyntaxError") {
|
27985
28056
|
print_error("Parse error at " + ex.filename + ":" + ex.line + "," + ex.col);
|
@@ -28042,14 +28113,18 @@ async function run_cli({ program, packageJson, fs, path }) {
|
|
28042
28113
|
}, 2));
|
28043
28114
|
} else if (program.output == "spidermonkey") {
|
28044
28115
|
try {
|
28045
|
-
const minified = await minify(
|
28046
|
-
|
28047
|
-
|
28048
|
-
|
28049
|
-
|
28050
|
-
|
28051
|
-
|
28052
|
-
|
28116
|
+
const minified = await minify(
|
28117
|
+
result.code,
|
28118
|
+
{
|
28119
|
+
compress: false,
|
28120
|
+
mangle: false,
|
28121
|
+
format: {
|
28122
|
+
ast: true,
|
28123
|
+
code: false
|
28124
|
+
}
|
28125
|
+
},
|
28126
|
+
fs
|
28127
|
+
);
|
28053
28128
|
console.log(JSON.stringify(minified.ast.to_mozilla_ast(), null, 2));
|
28054
28129
|
} catch (ex) {
|
28055
28130
|
fatal(ex);
|
package/lib/cli.js
CHANGED
@@ -224,7 +224,7 @@ export async function run_cli({ program, packageJson, fs, path }) {
|
|
224
224
|
|
225
225
|
let result;
|
226
226
|
try {
|
227
|
-
result = await minify(files, options);
|
227
|
+
result = await minify(files, options, fs);
|
228
228
|
} catch (ex) {
|
229
229
|
if (ex.name == "SyntaxError") {
|
230
230
|
print_error("Parse error at " + ex.filename + ":" + ex.line + "," + ex.col);
|
@@ -287,14 +287,18 @@ export async function run_cli({ program, packageJson, fs, path }) {
|
|
287
287
|
}, 2));
|
288
288
|
} else if (program.output == "spidermonkey") {
|
289
289
|
try {
|
290
|
-
const minified = await minify(
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
290
|
+
const minified = await minify(
|
291
|
+
result.code,
|
292
|
+
{
|
293
|
+
compress: false,
|
294
|
+
mangle: false,
|
295
|
+
format: {
|
296
|
+
ast: true,
|
297
|
+
code: false
|
298
|
+
}
|
299
|
+
},
|
300
|
+
fs
|
301
|
+
);
|
298
302
|
console.log(JSON.stringify(minified.ast.to_mozilla_ast(), null, 2));
|
299
303
|
} catch (ex) {
|
300
304
|
fatal(ex);
|
package/lib/minify.js
CHANGED
@@ -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
|
};
|
package/lib/output.js
CHANGED
@@ -172,7 +172,7 @@ function is_some_comments(comment) {
|
|
172
172
|
// multiline comment
|
173
173
|
return (
|
174
174
|
(comment.type === "comment2" || comment.type === "comment1")
|
175
|
-
&& /@preserve|@lic|@cc_on|^\**!/i.test(comment.value)
|
175
|
+
&& /@preserve|@copyright|@lic|@cc_on|^\**!/i.test(comment.value)
|
176
176
|
);
|
177
177
|
}
|
178
178
|
|
@@ -285,8 +285,8 @@ function OutputStream(options) {
|
|
285
285
|
var OUTPUT = new Rope();
|
286
286
|
let printed_comments = new Set();
|
287
287
|
|
288
|
-
var to_utf8 = options.ascii_only ? function(str, identifier) {
|
289
|
-
if (options.ecma >= 2015 && !options.safari10) {
|
288
|
+
var to_utf8 = options.ascii_only ? function(str, identifier = false, regexp = false) {
|
289
|
+
if (options.ecma >= 2015 && !options.safari10 && !regexp) {
|
290
290
|
str = str.replace(/[\ud800-\udbff][\udc00-\udfff]/g, function(ch) {
|
291
291
|
var code = get_full_char_code(ch, 0).toString(16);
|
292
292
|
return "\\u{" + code + "}";
|
@@ -1098,7 +1098,8 @@ function OutputStream(options) {
|
|
1098
1098
|
var p = output.parent();
|
1099
1099
|
if (this.args.length === 0
|
1100
1100
|
&& (p instanceof AST_PropAccess // (new Date).getTime(), (new Date)["getTime"]()
|
1101
|
-
|| p instanceof AST_Call && p.expression === this
|
1101
|
+
|| p instanceof AST_Call && p.expression === this
|
1102
|
+
|| p instanceof AST_PrefixedTemplateString && p.prefix === this)) // (new foo)(bar)
|
1102
1103
|
return true;
|
1103
1104
|
});
|
1104
1105
|
|
@@ -2213,7 +2214,7 @@ function OutputStream(options) {
|
|
2213
2214
|
flags = flags ? sort_regexp_flags(flags) : "";
|
2214
2215
|
source = source.replace(r_slash_script, slash_script_replace);
|
2215
2216
|
|
2216
|
-
output.print(output.to_utf8(`/${source}/${flags}
|
2217
|
+
output.print(output.to_utf8(`/${source}/${flags}`, false, true));
|
2217
2218
|
|
2218
2219
|
const parent = output.parent();
|
2219
2220
|
if (
|
package/lib/scope.js
CHANGED
@@ -116,6 +116,11 @@ const MASK_EXPORT_WANT_MANGLE = 1 << 1;
|
|
116
116
|
|
117
117
|
let function_defs = null;
|
118
118
|
let unmangleable_names = null;
|
119
|
+
/**
|
120
|
+
* When defined, there is a function declaration somewhere that's inside of a block.
|
121
|
+
* See https://tc39.es/ecma262/multipage/additional-ecmascript-features-for-web-browsers.html#sec-block-level-function-declarations-web-legacy-compatibility-semantics
|
122
|
+
*/
|
123
|
+
let scopes_with_block_defuns = null;
|
119
124
|
|
120
125
|
class SymbolDef {
|
121
126
|
constructor(scope, orig, init) {
|
@@ -666,6 +671,15 @@ AST_Scope.DEFMETHOD("def_variable", function(symbol, init) {
|
|
666
671
|
});
|
667
672
|
|
668
673
|
function next_mangled(scope, options) {
|
674
|
+
let defun_scope;
|
675
|
+
if (
|
676
|
+
scopes_with_block_defuns
|
677
|
+
&& (defun_scope = scope.get_defun_scope())
|
678
|
+
&& scopes_with_block_defuns.has(defun_scope)
|
679
|
+
) {
|
680
|
+
scope = defun_scope;
|
681
|
+
}
|
682
|
+
|
669
683
|
var ext = scope.enclosed;
|
670
684
|
var nth_identifier = options.nth_identifier;
|
671
685
|
out: while (true) {
|
@@ -800,6 +814,13 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
|
|
800
814
|
lname = save_nesting;
|
801
815
|
return true; // don't descend again in TreeWalker
|
802
816
|
}
|
817
|
+
if (
|
818
|
+
node instanceof AST_Defun
|
819
|
+
&& !(tw.parent() instanceof AST_Scope)
|
820
|
+
) {
|
821
|
+
scopes_with_block_defuns = scopes_with_block_defuns || new Set();
|
822
|
+
scopes_with_block_defuns.add(node.parent_scope.get_defun_scope());
|
823
|
+
}
|
803
824
|
if (node instanceof AST_Scope) {
|
804
825
|
node.variables.forEach(collect);
|
805
826
|
return;
|
@@ -848,6 +869,7 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
|
|
848
869
|
|
849
870
|
function_defs = null;
|
850
871
|
unmangleable_names = null;
|
872
|
+
scopes_with_block_defuns = null;
|
851
873
|
|
852
874
|
function collect(symbol) {
|
853
875
|
if (symbol.export & MASK_EXPORT_DONT_MANGLE) {
|
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.12.1",
|
8
8
|
"engines": {
|
9
9
|
"node": ">=10"
|
10
10
|
},
|
@@ -43,6 +43,7 @@
|
|
43
43
|
"main.js"
|
44
44
|
],
|
45
45
|
"dependencies": {
|
46
|
+
"acorn": "^8.5.0",
|
46
47
|
"commander": "^2.20.0",
|
47
48
|
"source-map": "~0.7.2",
|
48
49
|
"source-map-support": "~0.5.20"
|
@@ -53,20 +54,12 @@
|
|
53
54
|
"eslint": "^7.32.0",
|
54
55
|
"eslump": "^3.0.0",
|
55
56
|
"esm": "^3.2.25",
|
56
|
-
"mocha": "^9.
|
57
|
+
"mocha": "^9.2.0",
|
57
58
|
"pre-commit": "^1.2.2",
|
58
59
|
"rimraf": "^3.0.2",
|
59
60
|
"rollup": "2.56.3",
|
60
61
|
"semver": "^7.3.4"
|
61
62
|
},
|
62
|
-
"peerDependencies": {
|
63
|
-
"acorn": "^8.5.0"
|
64
|
-
},
|
65
|
-
"peerDependenciesMeta": {
|
66
|
-
"acorn": {
|
67
|
-
"optional": true
|
68
|
-
}
|
69
|
-
},
|
70
63
|
"scripts": {
|
71
64
|
"test": "node test/compress.js && mocha test/mocha",
|
72
65
|
"test:compress": "node test/compress.js",
|
@@ -111,6 +104,8 @@
|
|
111
104
|
"describe": false,
|
112
105
|
"it": false,
|
113
106
|
"require": false,
|
107
|
+
"before": false,
|
108
|
+
"after": false,
|
114
109
|
"global": false,
|
115
110
|
"process": false
|
116
111
|
},
|
package/bin/terser.mjs
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
#!/usr/bin/env node
|
2
|
-
|
3
|
-
"use strict";
|
4
|
-
|
5
|
-
import '../tools/exit.cjs'
|
6
|
-
import fs from 'fs'
|
7
|
-
import path from 'path'
|
8
|
-
import program from 'commander'
|
9
|
-
|
10
|
-
import { _run_cli as run_cli } from '../main.js'
|
11
|
-
|
12
|
-
const packageJson = {
|
13
|
-
name: 'terser',
|
14
|
-
version: 'development-cli'
|
15
|
-
}
|
16
|
-
run_cli({ program, packageJson, fs, path }).catch((error) => {
|
17
|
-
console.error(error);
|
18
|
-
process.exitCode = 1;
|
19
|
-
});
|