aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Lam S.L <alexlamsl@gmail.com>2018-04-06 16:04:15 +0800
committerGitHub <noreply@github.com>2018-04-06 16:04:15 +0800
commit923deeff35b708e49c4d8bcfa64dc53832cd4b5a (patch)
tree838a093941e36f1e4721f69d89300adb07243fb0
parent0b62a28b476c443638d9894e14e4c29b2748143c (diff)
downloadtracifyjs-923deeff35b708e49c4d8bcfa64dc53832cd4b5a.tar.gz
tracifyjs-923deeff35b708e49c4d8bcfa64dc53832cd4b5a.zip
support inline source map from multiple files (#3058)
fixes #145
-rw-r--r--lib/minify.js41
-rw-r--r--lib/sourcemap.js28
-rw-r--r--test/mocha/cli.js21
-rw-r--r--test/mocha/sourcemaps.js41
4 files changed, 83 insertions, 48 deletions
diff --git a/lib/minify.js b/lib/minify.js
index 0e117ed1..399b8615 100644
--- a/lib/minify.js
+++ b/lib/minify.js
@@ -7,15 +7,23 @@ var to_base64 = typeof btoa == "undefined" ? function(str) {
return new Buffer(str).toString("base64");
} : btoa;
-function read_source_map(code) {
+function read_source_map(name, code) {
var match = /\n\/\/# sourceMappingURL=data:application\/json(;.*?)?;base64,(.*)/.exec(code);
if (!match) {
- AST_Node.warn("inline source map not found");
+ AST_Node.warn("inline source map not found: " + name);
return null;
}
return to_ascii(match[2]);
}
+function parse_source_map(content) {
+ try {
+ return JSON.parse(content);
+ } catch (ex) {
+ throw new Error("invalid input source map: " + content);
+ }
+}
+
function set_shorthand(name, options, keys) {
if (options[name]) {
keys.forEach(function(key) {
@@ -113,7 +121,7 @@ function minify(files, options) {
};
}
if (timings) timings.parse = Date.now();
- var toplevel;
+ var source_maps, toplevel;
if (files instanceof AST_Toplevel) {
toplevel = files;
} else {
@@ -122,13 +130,23 @@ function minify(files, options) {
}
options.parse = options.parse || {};
options.parse.toplevel = null;
+ var source_map_content = options.sourceMap && options.sourceMap.content;
+ 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);
for (var name in files) if (HOP(files, name)) {
options.parse.filename = name;
options.parse.toplevel = parse(files[name], options.parse);
- if (options.sourceMap && options.sourceMap.content == "inline") {
- if (Object.keys(files).length > 1)
- throw new Error("inline source map only works with singular input");
- options.sourceMap.content = read_source_map(files[name]);
+ if (source_maps) {
+ if (source_map_content == "inline") {
+ var inlined_content = read_source_map(name, files[name]);
+ if (inlined_content) {
+ source_maps[name] = parse_source_map(inlined_content);
+ }
+ } else {
+ source_maps[name] = source_map_content;
+ }
}
}
toplevel = options.parse.toplevel;
@@ -164,16 +182,9 @@ function minify(files, options) {
}
if (!HOP(options.output, "code") || options.output.code) {
if (options.sourceMap) {
- if (typeof options.sourceMap.content == "string") {
- try {
- options.sourceMap.content = JSON.parse(options.sourceMap.content);
- } catch (ex) {
- throw new Error("invalid input source map: " + options.sourceMap.content);
- }
- }
options.output.source_map = SourceMap({
file: options.sourceMap.filename,
- orig: options.sourceMap.content,
+ orig: source_maps,
root: options.sourceMap.root
});
if (options.sourceMap.includeSources) {
diff --git a/lib/sourcemap.js b/lib/sourcemap.js
index 0be16bfc..dcb8e476 100644
--- a/lib/sourcemap.js
+++ b/lib/sourcemap.js
@@ -57,26 +57,26 @@ function SourceMap(options) {
file : options.file,
sourceRoot : options.root
});
- var orig_map = options.orig && new MOZ_SourceMap.SourceMapConsumer(options.orig);
-
- if (orig_map && Array.isArray(options.orig.sources)) {
- orig_map._sources.toArray().forEach(function(source) {
- var sourceContent = orig_map.sourceContentFor(source, true);
- if (sourceContent) {
- generator.setSourceContent(source, sourceContent);
- }
- });
+ var maps = options.orig && Object.create(null);
+ if (maps) for (var source in options.orig) {
+ var map = new MOZ_SourceMap.SourceMapConsumer(options.orig[source]);
+ if (Array.isArray(options.orig[source].sources)) {
+ map._sources.toArray().forEach(function(source) {
+ var sourceContent = map.sourceContentFor(source, true);
+ if (sourceContent) generator.setSourceContent(source, sourceContent);
+ });
+ }
+ maps[source] = map;
}
function add(source, gen_line, gen_col, orig_line, orig_col, name) {
- if (orig_map) {
- var info = orig_map.originalPositionFor({
+ var map = maps && maps[source];
+ if (map) {
+ var info = map.originalPositionFor({
line: orig_line,
column: orig_col
});
- if (info.source === null) {
- return;
- }
+ if (info.source === null) return;
source = info.source;
orig_line = info.line;
orig_col = info.column;
diff --git a/test/mocha/cli.js b/test/mocha/cli.js
index a64cb216..8c858bd9 100644
--- a/test/mocha/cli.js
+++ b/test/mocha/cli.js
@@ -244,16 +244,27 @@ describe("bin/uglifyjs", function () {
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvaW5wdXQvaXNzdWUtMTMyMy9zYW1wbGUuanMiXSwibmFtZXMiOlsiYmFyIiwiZm9vIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFJQSxJQUFNLFdBQ04sU0FBU0MsSUFBS0QsS0FDVixPQUFPQSxJQUdYLE9BQU9DLElBTEQifQ==",
"",
].join("\n"));
- assert.strictEqual(stderr, "WARN: inline source map not found\n");
+ assert.strictEqual(stderr, "WARN: inline source map not found: test/input/issue-1323/sample.js\n");
done();
});
});
- it("Should fail with multiple input and inline source map", function(done) {
- var command = uglifyjscmd + " test/input/issue-520/input.js test/input/issue-520/output.js --source-map content=inline,url=inline";
+ it("Should handle multiple input and inline source map", function(done) {
+ var command = [
+ uglifyjscmd,
+ "test/input/issue-520/input.js",
+ "test/input/issue-1323/sample.js",
+ "--source-map", "content=inline,url=inline",
+ ].join(" ");
exec(command, function (err, stdout, stderr) {
- assert.ok(err);
- assert.strictEqual(stderr.split(/\n/)[0], "ERROR: inline source map only works with singular input");
+ if (err) throw err;
+
+ assert.strictEqual(stdout, [
+ "var Foo=function Foo(){console.log(1+2)};new Foo;var bar=function(){function foo(bar){return bar}return foo}();",
+ "//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZGluIiwidGVzdC9pbnB1dC9pc3N1ZS0xMzIzL3NhbXBsZS5qcyJdLCJuYW1lcyI6WyJGb28iLCJjb25zb2xlIiwibG9nIiwiYmFyIiwiZm9vIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFNQSxJQUFJLFNBQUFBLE1BQWdCQyxRQUFRQyxJQUFJLEVBQUUsSUFBTyxJQUFJRixJQ0FuRCxJQUFJRyxJQUFNLFdBQ04sU0FBU0MsSUFBS0QsS0FDVixPQUFPQSxJQUdYLE9BQU9DLElBTEQifQ==",
+ "",
+ ].join("\n"));
+ assert.strictEqual(stderr, "WARN: inline source map not found: test/input/issue-1323/sample.js\n");
done();
});
});
diff --git a/test/mocha/sourcemaps.js b/test/mocha/sourcemaps.js
index 8868c5ae..2f178b27 100644
--- a/test/mocha/sourcemaps.js
+++ b/test/mocha/sourcemaps.js
@@ -91,24 +91,37 @@ describe("sourcemaps", function() {
});
assert.strictEqual(result.code, "var bar=function(bar){return bar};");
assert.strictEqual(warnings.length, 1);
- assert.strictEqual(warnings[0], "inline source map not found");
+ assert.strictEqual(warnings[0], "inline source map not found: 0");
} finally {
Uglify.AST_Node.warn_function = warn_function;
}
});
- it("Should fail with multiple input and inline source map", function() {
- var result = Uglify.minify([
- read("./test/input/issue-520/input.js"),
- read("./test/input/issue-520/output.js")
- ], {
- sourceMap: {
- content: "inline",
- url: "inline"
- }
- });
- var err = result.error;
- assert.ok(err instanceof Error);
- assert.strictEqual(err.stack.split(/\n/)[0], "Error: inline source map only works with singular input");
+ it("Should handle multiple input and inline source map", function() {
+ var warn_function = Uglify.AST_Node.warn_function;
+ var warnings = [];
+ Uglify.AST_Node.warn_function = function(txt) {
+ warnings.push(txt);
+ };
+ try {
+ var result = Uglify.minify([
+ read("./test/input/issue-520/input.js"),
+ read("./test/input/issue-1323/sample.js"),
+ ], {
+ sourceMap: {
+ content: "inline",
+ url: "inline",
+ }
+ });
+ if (result.error) throw result.error;
+ assert.strictEqual(result.code, [
+ "var Foo=function(){console.log(3)};new Foo;var bar=function(o){return o};",
+ "//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZGluIiwiMSJdLCJuYW1lcyI6WyJGb28iLCJjb25zb2xlIiwibG9nIiwiYmFyIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFNQSxJQUFJLFdBQWdCQyxRQUFRQyxJQUFJLElBQVMsSUFBSUYsSUNBbkQsSUFBSUcsSUFDQSxTQUFjQSxHQUNWLE9BQU9BIn0=",
+ ].join("\n"));
+ assert.strictEqual(warnings.length, 1);
+ assert.strictEqual(warnings[0], "inline source map not found: 1");
+ } finally {
+ Uglify.AST_Node.warn_function = warn_function;
+ }
});
it("Should drop source contents for includeSources=false", function() {
var result = Uglify.minify(read("./test/input/issue-520/input.js"), {