From: Alex Lam S.L Date: Thu, 16 Apr 2020 23:20:48 +0000 (+0100) Subject: support optional output of `names` in source maps (#3784) X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=83f42ede367316193205572a04959098b45e711d;p=UglifyJS.git support optional output of `names` in source maps (#3784) --- diff --git a/README.md b/README.md index 7e07cc87..c22808d8 100644 --- a/README.md +++ b/README.md @@ -126,6 +126,7 @@ a double dash to prevent input files being used as option arguments: `includeSources` Pass this flag if you want to include the content of source files in the source map as sourcesContent property. + `names` Include symbol names in the source map. `root` Path to the original source to be included in the source map. `url` If specified, path to the source map to append in @@ -159,6 +160,9 @@ Additional options: - `--source-map "root=''"` to pass the URL where the original files can be found. +- `--source-map "names=false"` to omit symbol names if you want to reduce size + of the source map file. + - `--source-map "url=''"` to specify the URL where the source map can be found. Otherwise UglifyJS assumes HTTP `X-SourceMap` is being used and will omit the `//# sourceMappingURL=` directive. @@ -593,6 +597,9 @@ var result = UglifyJS.minify({"compiled.js": "compiled code"}, { If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.url`. +If you wish to reduce file size of the source map, set option `sourceMap.names` +to be `false` and all symbol names will be omitted. + ## Parse options - `bare_returns` (default `false`) -- support top level `return` statements diff --git a/lib/minify.js b/lib/minify.js index ab397f5e..2182d653 100644 --- a/lib/minify.js +++ b/lib/minify.js @@ -129,6 +129,7 @@ function minify(files, options) { content: null, filename: null, includeSources: false, + names: true, root: null, url: null, }, true); @@ -138,7 +139,7 @@ function minify(files, options) { warnings.push(warning); }, options.warnings == "verbose"); if (timings) timings.parse = Date.now(); - var source_maps, toplevel; + var toplevel; if (files instanceof AST_Toplevel) { toplevel = files; } else { @@ -151,19 +152,17 @@ function minify(files, options) { if (typeof source_map_content == "string" && source_map_content != "inline") { source_map_content = parse_source_map(source_map_content); } - source_maps = source_map_content && Object.create(null); + if (source_map_content) options.sourceMap.orig = Object.create(null); for (var name in files) if (HOP(files, name)) { options.parse.filename = name; options.parse.toplevel = toplevel = parse(files[name], options.parse); - if (source_maps) { - if (source_map_content == "inline") { - var inlined_content = read_source_map(name, toplevel); - if (inlined_content) { - source_maps[name] = parse_source_map(inlined_content); - } - } else { - source_maps[name] = source_map_content; + if (source_map_content == "inline") { + var inlined_content = read_source_map(name, toplevel); + if (inlined_content) { + options.sourceMap.orig[name] = parse_source_map(inlined_content); } + } else if (source_map_content) { + options.sourceMap.orig[name] = source_map_content; } } } @@ -202,12 +201,7 @@ function minify(files, options) { } if (!HOP(options.output, "code") || options.output.code) { if (options.sourceMap) { - options.output.source_map = SourceMap({ - content: options.sourceMap.includeSources, - file: options.sourceMap.filename, - orig: source_maps, - root: options.sourceMap.root - }); + options.output.source_map = SourceMap(options.sourceMap); if (options.sourceMap.includeSources) { if (files instanceof AST_Toplevel) { throw new Error("original source content unavailable"); diff --git a/lib/sourcemap.js b/lib/sourcemap.js index fc200ced..0e982f09 100644 --- a/lib/sourcemap.js +++ b/lib/sourcemap.js @@ -90,14 +90,8 @@ function create_array_map() { } function SourceMap(options) { - options = defaults(options, { - content: false, - file: null, - root: null, - orig: null, - }, true); var sources = create_array_map(); - var sources_content = options.content && Object.create(null); + var sources_content = options.includeSources && Object.create(null); var names = create_array_map(); var mappings = ""; if (options.orig) Object.keys(options.orig).forEach(function(name) { @@ -155,7 +149,7 @@ function SourceMap(options) { toString: function() { return JSON.stringify({ version: 3, - file: options.file || undefined, + file: options.filename || undefined, sourceRoot: options.root || undefined, sources: sources, sourcesContent: sources_content ? sources.map(function(source) { @@ -188,7 +182,7 @@ function SourceMap(options) { original_line = orig_line; mappings += vlq_encode(orig_col - original_column); original_column = orig_col; - if (name != null) { + if (options.names && name != null) { var name_idx = names.index(name); mappings += vlq_encode(name_idx - name_index); name_index = name_idx; diff --git a/test/mocha/cli.js b/test/mocha/cli.js index 8642a6b4..5f29bbdc 100644 --- a/test/mocha/cli.js +++ b/test/mocha/cli.js @@ -2,6 +2,7 @@ var assert = require("assert"); var exec = require("child_process").exec; var fs = require("fs"); var run_code = require("../sandbox").run_code; +var to_ascii = require("../node").to_ascii; function read(path) { return fs.readFileSync(path, "utf8"); @@ -48,6 +49,62 @@ describe("bin/uglifyjs", function() { done(); }); }); + it("Should work with --source-map names=true", function(done) { + exec([ + uglifyjscmd, + "--beautify", + "--source-map", [ + "names=true", + "url=inline", + ].join(","), + ].join(" "), function(err, stdout) { + if (err) throw err; + var expected = [ + "var obj = {", + " p: a,", + " q: b", + "};", + "//# sourceMappingURL=data:application/json;charset=utf-8;base64,", + ].join("\n") + assert.strictEqual(stdout.slice(0, expected.length), expected); + var map = JSON.parse(to_ascii(stdout.slice(expected.length).trim())); + assert.deepEqual(map.names, [ "obj", "p", "a", "q", "b" ]); + done(); + }).stdin.end([ + "var obj = {", + " p: a,", + " q: b", + "};", + ].join("\n")); + }); + it("Should work with --source-map names=false", function(done) { + exec([ + uglifyjscmd, + "--beautify", + "--source-map", [ + "names=false", + "url=inline", + ].join(","), + ].join(" "), function(err, stdout) { + if (err) throw err; + var expected = [ + "var obj = {", + " p: a,", + " q: b", + "};", + "//# sourceMappingURL=data:application/json;charset=utf-8;base64,", + ].join("\n") + assert.strictEqual(stdout.slice(0, expected.length), expected); + var map = JSON.parse(to_ascii(stdout.slice(expected.length).trim())); + assert.deepEqual(map.names, []); + done(); + }).stdin.end([ + "var obj = {", + " p: a,", + " q: b", + "};", + ].join("\n")); + }); it("Should give sensible error against invalid input source map", function(done) { var command = uglifyjscmd + " test/mocha.js --source-map content=blah,url=inline --verbose"; exec(command, function(err, stdout, stderr) { diff --git a/test/mocha/sourcemaps.js b/test/mocha/sourcemaps.js index 23698c57..91b38cd2 100644 --- a/test/mocha/sourcemaps.js +++ b/test/mocha/sourcemaps.js @@ -7,11 +7,13 @@ function read(path) { } function source_map(code) { - return JSON.parse(UglifyJS.minify(code, { + var result = UglifyJS.minify(code, { compress: false, mangle: false, sourceMap: true, - }).map); + }); + if (result.error) throw result.error; + return JSON.parse(result.map); } function get_map() { @@ -65,6 +67,40 @@ describe("sourcemaps", function() { ].join("\n")); assert.deepEqual(map.names, [ "enabled", "x" ]); }); + it("Should work with sourceMap.names=true", function() { + var result = UglifyJS.minify([ + "var obj = {", + " p: a,", + " q: b", + "};", + ].join("\n"), { + compress: false, + mangle: false, + sourceMap: { + names: true, + }, + }); + if (result.error) throw result.error; + var map = JSON.parse(result.map); + assert.deepEqual(map.names, [ "obj", "p", "a", "q", "b" ]); + }); + it("Should work with sourceMap.names=false", function() { + var result = UglifyJS.minify([ + "var obj = {", + " p: a,", + " q: b", + "};", + ].join("\n"), { + compress: false, + mangle: false, + sourceMap: { + names: false, + }, + }); + if (result.error) throw result.error; + var map = JSON.parse(result.map); + assert.deepEqual(map.names, []); + }); it("Should mark array/object literals", function() { var result = UglifyJS.minify([ "var obj = {};",