This commit is contained in:
Fábio Santos 2018-03-19 16:46:27 +00:00 committed by GitHub
commit a6c7f8d19e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 91 additions and 1 deletions

View File

@ -110,6 +110,8 @@ a double dash to prevent input files being used as option arguments:
--keep-classnames Do not mangle/drop class names.
--keep-fnames Do not mangle/drop function names. Useful for
code relying on Function.prototype.name.
--module Input is an ES6 module. If `compress` or `mangle` is
enabled then the `toplevel` option will be enabled.
--name-cache <file> File to hold mangled name mappings.
--safari10 Support non-standard Safari 10/11.
Equivalent to setting `safari10: true` in `minify()`
@ -496,6 +498,10 @@ if (result.error) throw result.error;
- `mangle.properties` (default `false`) — a subcategory of the mangle option.
Pass an object to specify custom [mangle property options](#mangle-properties-options).
- `module` (default `false`) — Use when minifying an ES6 module. "use strict"
is implied and names can be mangled on the top scope. If `compress` or
`mangle` is enabled then the `toplevel` option will be enabled.
- `output` (default `null`) — pass an object if you wish to specify
additional [output options](#output-options). The defaults are optimized
for best compression.
@ -554,6 +560,7 @@ if (result.error) throw result.error;
keep_classnames: false,
keep_fnames: false,
ie8: false,
module: false,
nameCache: null, // or specify a name cache object
safari10: false,
toplevel: false,
@ -702,6 +709,9 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u
- `loops` (default: `true`) -- optimizations for `do`, `while` and `for` loops
when we can statically determine the condition.
- `module` (default `false`) -- Pass `true` when compressing an ES6 module. Strict
mode is implied and the `toplevel` option as well.
- `negate_iife` (default: `true`) -- negate "Immediately-Called Function Expressions"
where the return value is discarded, to avoid the parens that the
code generator would insert.
@ -823,6 +833,9 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u
Useful for code relying on `Function.prototype.name`. See also: the `keep_fnames`
[compress option](#compress-options).
- `module` (default `false`) -- Pass `true` an ES6 modules, where the toplevel
scope is not the global scope. Implies `toplevel`.
- `reserved` (default `[]`) -- Pass an array of identifiers that should be
excluded from mangling. Example: `["foo", "bar"]`.

View File

@ -44,6 +44,7 @@ program.option("--ecma <version>", "Specify ECMAScript release: 5, 6, 7 or 8.");
program.option("--ie8", "Support non-standard Internet Explorer 8.");
program.option("--keep-classnames", "Do not mangle/drop class names.");
program.option("--keep-fnames", "Do not mangle/drop function names. Useful for code relying on Function.prototype.name.");
program.option("--module", "Input is an ES6 module");
program.option("--name-cache <file>", "File to hold mangled name mappings.");
program.option("--rename", "Force symbol expansion.");
program.option("--no-rename", "Disable symbol expansion.");
@ -66,6 +67,7 @@ if (!program.output && program.sourceMap && program.sourceMap.url != "inline") {
"compress",
"ie8",
"mangle",
"module",
"safari10",
"sourceMap",
"toplevel",
@ -195,7 +197,8 @@ function run() {
return require("acorn").parse(files[name], {
locations: true,
program: toplevel,
sourceFile: name
sourceFile: name,
sourceType: options.module || program.parse.module ? "module" : "script"
});
});
} else if (program.parse.spidermonkey) {

View File

@ -73,6 +73,7 @@ function Compressor(options, false_by_default) {
keep_fnames : false,
keep_infinity : false,
loops : !false_by_default,
module : false,
negate_iife : !false_by_default,
passes : 1,
properties : !false_by_default,
@ -130,6 +131,10 @@ function Compressor(options, false_by_default) {
return top_retain.indexOf(def.name) >= 0;
};
}
if (this.options["module"]) {
this.directives["use strict"] = true;
this.options["toplevel"] = true;
}
var toplevel = this.options["toplevel"];
this.toplevel = typeof toplevel == "string" ? {
funcs: /funcs/.test(toplevel),

View File

@ -52,6 +52,7 @@ function minify(files, options) {
keep_classnames: undefined,
keep_fnames: false,
mangle: {},
module: false,
nameCache: null,
output: {},
parse: {},
@ -76,6 +77,7 @@ function minify(files, options) {
set_shorthand("ie8", options, [ "compress", "mangle", "output" ]);
set_shorthand("keep_classnames", options, [ "compress", "mangle" ]);
set_shorthand("keep_fnames", options, [ "compress", "mangle" ]);
set_shorthand("module", options, [ "parse", "compress", "mangle" ]);
set_shorthand("safari10", options, [ "mangle", "output" ]);
set_shorthand("toplevel", options, [ "compress", "mangle" ]);
set_shorthand("warnings", options, [ "compress" ]);
@ -87,6 +89,7 @@ function minify(files, options) {
ie8: false,
keep_classnames: false,
keep_fnames: false,
module: false,
properties: false,
reserved: [],
safari10: false,

View File

@ -859,6 +859,7 @@ function parse($TEXT, options) {
expression : false,
filename : null,
html5_comments : true,
module : false,
shebang : true,
strict : false,
toplevel : null,
@ -2913,6 +2914,7 @@ function parse($TEXT, options) {
var start = S.token;
var body = [];
S.input.push_directives_stack();
if (options.module) S.input.add_directive("use strict");
while (!is("eof"))
body.push(statement());
S.input.pop_directives_stack();

View File

@ -514,9 +514,13 @@ AST_Toplevel.DEFMETHOD("_default_mangler_options", function(options) {
ie8 : false,
keep_classnames: false,
keep_fnames : false,
module : false,
reserved : [],
toplevel : false,
});
if (options["module"]) {
options.toplevel = true;
}
if (!Array.isArray(options.reserved)) options.reserved = [];
// Never mangle arguments
push_uniq(options.reserved, "arguments");

View File

@ -1601,3 +1601,52 @@ issue_2874_3: {
]
node_version: ">=6"
}
module_enables_strict_mode: {
options = {
module: true,
}
input: {
if (1) {
function xyz() {}
}
}
expect: {
if (1) {
function xyz() {}
}
}
}
module_mangle_scope: {
mangle = {
module: true
}
input: {
let a = 10;
}
expect: {
let e = 10;
}
}
module_enabled: {
options = {
module: true,
reduce_vars: true,
unused: true,
}
mangle = {
module: true,
}
input: {
let apple = 10, b = 20;
console.log(apple++, b, apple++);
export { apple };
}
expect: {
let o = 10;
console.log(o++, 20, o++);
export { o as apple };
}
}

View File

@ -0,0 +1,2 @@
let foo = 1, bar = 2;
export { foo };

View File

@ -734,6 +734,15 @@ describe("bin/uglifyjs", function () {
done();
});
});
it("Should mangle toplevel names with the --module option", function(done) {
var command = uglifyjscmd + " test/input/module/input.js --module -mc";
exec(command, function (err, stdout, stderr) {
if (err) throw err;
assert.strictEqual(stdout, "let e=1;export{e as foo};\n")
done();
});
});
it("Should fail with --define a-b", function(done) {
var command = uglifyjscmd + " test/input/issue-505/input.js --define a-b";
exec(command, function (err, stdout, stderr) {