support optional output of names in source maps (#3784)
This commit is contained in:
@@ -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='<URL>'"` 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='<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
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 = {};",
|
||||
|
||||
Reference in New Issue
Block a user