From 354fec8a9c3c8540d7e964ecbfcb38deaae86a3e Mon Sep 17 00:00:00 2001 From: "Alex Lam S.L" Date: Sat, 4 May 2019 20:25:52 +0800 Subject: [PATCH] make `enclose` & `wrap` work with `sourceMap` (#3396) fixes #3313 --- README.md | 3 --- bin/uglifyjs | 34 ++++++++++++++++++---------------- lib/ast.js | 23 ++++++++++++++++------- lib/minify.js | 13 +++++++------ test/mocha/cli.js | 2 +- test/mocha/minify.js | 2 +- 6 files changed, 43 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index bf8fbd23..a4f76229 100644 --- a/README.md +++ b/README.md @@ -767,9 +767,6 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u - `unused` (default: `true`) -- drop unreferenced functions and variables (simple direct variable assignments do not count as references unless set to `"keep_assign"`) -- `warnings` (default: `false`) -- display warnings when dropping unreachable - code or unused declarations etc. - ## Mangle options - `eval` (default `false`) -- Pass `true` to mangle names visible in scopes diff --git a/bin/uglifyjs b/bin/uglifyjs index 35207bf7..ace94e7e 100755 --- a/bin/uglifyjs +++ b/bin/uglifyjs @@ -215,24 +215,26 @@ function run() { var ex = result.error; if (ex.name == "SyntaxError") { print_error("Parse error at " + ex.filename + ":" + ex.line + "," + ex.col); - var col = ex.col; - var lines = files[ex.filename].split(/\r?\n/); - var line = lines[ex.line - 1]; - if (!line && !col) { - line = lines[ex.line - 2]; - col = line.length; - } - if (line) { - var limit = 70; - if (col > limit) { - line = line.slice(col - limit); - col = limit; + var file = files[ex.filename]; + if (file) { + var col = ex.col; + var lines = file.split(/\r?\n/); + var line = lines[ex.line - 1]; + if (!line && !col) { + line = lines[ex.line - 2]; + col = line.length; + } + if (line) { + var limit = 70; + if (col > limit) { + line = line.slice(col - limit); + col = limit; + } + print_error(line.slice(0, 80)); + print_error(line.slice(0, col).replace(/\S/g, " ") + "^"); } - print_error(line.slice(0, 80)); - print_error(line.slice(0, col).replace(/\S/g, " ") + "^"); } - } - if (ex.defs) { + } else if (ex.defs) { print_error("Supported options:"); print_error(format_object(ex.defs)); } diff --git a/lib/ast.js b/lib/ast.js index f75670e6..1ced7631 100644 --- a/lib/ast.js +++ b/lib/ast.js @@ -337,18 +337,25 @@ var AST_Toplevel = DEFNODE("Toplevel", "globals", { $propdoc: { globals: "[Object/S] a map of name -> SymbolDef for all undeclared names", }, - wrap_commonjs: function(name) { + wrap: function(name) { var body = this.body; - var wrapped_tl = "(function(exports){'$ORIG';})(typeof " + name + "=='undefined'?(" + name + "={}):" + name + ");"; - wrapped_tl = parse(wrapped_tl); - wrapped_tl = wrapped_tl.transform(new TreeTransformer(function(node) { + return parse([ + "(function(exports){'$ORIG';})(typeof ", + name, + "=='undefined'?(", + name, + "={}):", + name, + ");" + ].join(""), { + filename: "wrap=" + JSON.stringify(name) + }).transform(new TreeTransformer(function(node) { if (node instanceof AST_Directive && node.value == "$ORIG") { return MAP.splice(body); } })); - return wrapped_tl; }, - wrap_enclose: function(args_values) { + enclose: function(args_values) { if (typeof args_values != "string") args_values = ""; var index = args_values.indexOf(":"); if (index < 0) index = args_values.length; @@ -359,7 +366,9 @@ var AST_Toplevel = DEFNODE("Toplevel", "globals", { '){"$ORIG"})(', args_values.slice(index + 1), ")" - ].join("")).transform(new TreeTransformer(function(node) { + ].join(""), { + filename: "enclose=" + JSON.stringify(args_values) + }).transform(new TreeTransformer(function(node) { if (node instanceof AST_Directive && node.value == "$ORIG") { return MAP.splice(body); } diff --git a/lib/minify.js b/lib/minify.js index 1bb6309c..9eebc373 100644 --- a/lib/minify.js +++ b/lib/minify.js @@ -151,12 +151,13 @@ function minify(files, options) { if (quoted_props) { reserve_quoted_keys(toplevel, quoted_props); } - if (options.wrap) { - toplevel = toplevel.wrap_commonjs(options.wrap); - } - if (options.enclose) { - toplevel = toplevel.wrap_enclose(options.enclose); - } + [ "enclose", "wrap" ].forEach(function(action) { + var option = options[action]; + if (!option) return; + var orig = toplevel.print_to_string().slice(0, -1); + toplevel = toplevel[action](option); + files[toplevel.start.file] = toplevel.print_to_string().replace(orig, ""); + }); if (timings) timings.rename = Date.now(); if (options.rename) { toplevel.figure_out_scope(options.mangle); diff --git a/test/mocha/cli.js b/test/mocha/cli.js index f99a8be4..7a484487 100644 --- a/test/mocha/cli.js +++ b/test/mocha/cli.js @@ -712,7 +712,7 @@ describe("bin/uglifyjs", function() { var command = uglifyjscmd + " test/input/enclose/input.js --enclose window,undefined:window --wrap exports"; exec(command, function(err, stdout, stderr) { if (err) throw err; - assert.strictEqual(stdout, '(function(window,undefined){(function(exports){function enclose(){console.log("test enclose")}enclose()})(typeof exports=="undefined"?exports={}:exports)})(window);\n'); + assert.strictEqual(stdout, '(function(exports){(function(window,undefined){function enclose(){console.log("test enclose")}enclose()})(window)})(typeof exports=="undefined"?exports={}:exports);\n'); done(); }); }); diff --git a/test/mocha/minify.js b/test/mocha/minify.js index d11f40ff..786edd80 100644 --- a/test/mocha/minify.js +++ b/test/mocha/minify.js @@ -365,7 +365,7 @@ describe("minify", function() { wrap: 'exports', }); if (result.error) throw result.error; - assert.strictEqual(result.code, '(function(window,undefined){(function(exports){function enclose(){console.log("test enclose")}enclose()})(typeof exports=="undefined"?exports={}:exports)})(window);'); + assert.strictEqual(result.code, '(function(exports){(function(window,undefined){function enclose(){console.log("test enclose")}enclose()})(window)})(typeof exports=="undefined"?exports={}:exports);'); }); }); }); -- 2.34.1