Add an option for writing inline source map

This commit is contained in:
pengzhenqing
2016-10-09 14:15:25 +08:00
committed by Richard van Velzen
parent 6389e52305
commit e51c6ba380
6 changed files with 75 additions and 14 deletions

View File

@@ -62,6 +62,7 @@ The available options are:
--source-map-include-sources Pass this flag if you want to include the --source-map-include-sources Pass this flag if you want to include the
content of source files in the source map as content of source files in the source map as
sourcesContent property. sourcesContent property.
--source-map-inline Write base64-encoded source map to the end of js output.
--in-source-map Input source map, useful if you're compressing --in-source-map Input source map, useful if you're compressing
JS that was generated from some other original JS that was generated from some other original
code. code.
@@ -641,7 +642,9 @@ var result = UglifyJS.minify({"file1.js": "var a = function () {};"}, {
Note that the source map is not saved in a file, it's just returned in Note that the source map is not saved in a file, it's just returned in
`result.map`. The value passed for `outSourceMap` is only used to set the `result.map`. The value passed for `outSourceMap` is only used to set the
`file` attribute in the source map (see [the spec][sm-spec]). `file` attribute in the source map (see [the spec][sm-spec]). You can set
option `sourceMapInline` to be `true` and source map will be appended to
code.
You can also specify sourceRoot property to be included in source map: You can also specify sourceRoot property to be included in source map:
```javascript ```javascript

View File

@@ -23,6 +23,7 @@ mangling you need to use `-c` and `-m`.\
.describe("source-map", "Specify an output file where to generate source map.") .describe("source-map", "Specify an output file where to generate source map.")
.describe("source-map-root", "The path to the original source to be included in the source map.") .describe("source-map-root", "The path to the original source to be included in the source map.")
.describe("source-map-url", "The path to the source map to be added in //# sourceMappingURL. Defaults to the value passed with --source-map.") .describe("source-map-url", "The path to the source map to be added in //# sourceMappingURL. Defaults to the value passed with --source-map.")
.describe("source-map-inline", "Write base64-encoded source map to the end of js output. Disabled by default")
.describe("source-map-include-sources", "Pass this flag if you want to include the content of source files in the source map as sourcesContent property.") .describe("source-map-include-sources", "Pass this flag if you want to include the content of source files in the source map as sourcesContent property.")
.describe("in-source-map", "Input source map, useful if you're compressing JS that was generated from some other original code.") .describe("in-source-map", "Input source map, useful if you're compressing JS that was generated from some other original code.")
.describe("screw-ie8", "Do not support Internet Explorer 6-8 quirks. This flag is enabled by default.") .describe("screw-ie8", "Do not support Internet Explorer 6-8 quirks. This flag is enabled by default.")
@@ -113,6 +114,7 @@ You need to pass an argument to this option to specify the name that your module
.array("pure-funcs") .array("pure-funcs")
.boolean("expr") .boolean("expr")
.boolean("source-map-inline")
.boolean("source-map-include-sources") .boolean("source-map-include-sources")
.boolean("screw-ie8") .boolean("screw-ie8")
.boolean("support-ie8") .boolean("support-ie8")
@@ -309,7 +311,7 @@ var TOPLEVEL = null;
var P_RELATIVE = ARGS.p && ARGS.p == "relative"; var P_RELATIVE = ARGS.p && ARGS.p == "relative";
var SOURCES_CONTENT = {}; var SOURCES_CONTENT = {};
var SOURCE_MAP = ARGS.source_map ? UglifyJS.SourceMap({ var SOURCE_MAP = (ARGS.source_map || ARGS.source_map_inline) ? UglifyJS.SourceMap({
file: P_RELATIVE ? path.relative(path.dirname(ARGS.source_map), OUTPUT_FILE) : OUTPUT_FILE, file: P_RELATIVE ? path.relative(path.dirname(ARGS.source_map), OUTPUT_FILE) : OUTPUT_FILE,
root: ARGS.source_map_root, root: ARGS.source_map_root,
orig: ORIG_MAP, orig: ORIG_MAP,
@@ -474,6 +476,10 @@ async.eachLimit(files, 1, function (file, cb) {
output = output.get(); output = output.get();
if (SOURCE_MAP) { if (SOURCE_MAP) {
if (ARGS.source_map_inline) {
var base64_string = new Buffer(SOURCE_MAP.toString()).toString('base64');
output += "\n//# sourceMappingURL=data:application/json;charset=utf-8;base64," + base64_string;
} else {
fs.writeFileSync(ARGS.source_map, SOURCE_MAP, "utf8"); fs.writeFileSync(ARGS.source_map, SOURCE_MAP, "utf8");
var source_map_url = ARGS.source_map_url || ( var source_map_url = ARGS.source_map_url || (
P_RELATIVE P_RELATIVE
@@ -482,6 +488,7 @@ async.eachLimit(files, 1, function (file, cb) {
); );
output += "\n//# sourceMappingURL=" + source_map_url; output += "\n//# sourceMappingURL=" + source_map_url;
} }
}
if (OUTPUT_FILE) { if (OUTPUT_FILE) {
fs.writeFileSync(OUTPUT_FILE, output, "utf8"); fs.writeFileSync(OUTPUT_FILE, output, "utf8");

View File

@@ -0,0 +1,7 @@
var bar = (function () {
function foo (bar) {
return bar;
}
return foo;
})();

View File

@@ -49,4 +49,25 @@ describe("bin/uglifyjs", function () {
done(); done();
}); });
}); });
it("Should append source map to output when using --source-map-inline", function (done) {
var command = uglifyjscmd + ' test/input/issue-1323/sample.js --source-map-inline';
exec(command, function (err, stdout) {
if (err) throw err;
assert.strictEqual(stdout, "var bar=function(){function foo(bar){return bar}return foo}();\n" +
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvaW5wdXQvaXNzdWUtMTMyMy9zYW1wbGUuanMiXSwibmFtZXMiOlsiYmFyIiwiZm9vIl0sIm1hcHBpbmdzIjoiQUFBQSxHQUFJQSxLQUFNLFdBQ04sUUFBU0MsS0FBS0QsS0FDVixNQUFPQSxLQUdYLE1BQU9DIn0=\n");
done();
});
});
it("should not append source map to output when not using --source-map-inline", function (done) {
var command = uglifyjscmd + ' test/input/issue-1323/sample.js';
exec(command, function (err, stdout) {
if (err) throw err;
assert.strictEqual(stdout, "var bar=function(){function foo(bar){return bar}return foo}();\n");
done();
});
});
}); });

View File

@@ -75,4 +75,23 @@ describe("minify", function() {
'let foo = x => "foo " + x;\nconsole.log(foo("bar"));'); 'let foo = x => "foo " + x;\nconsole.log(foo("bar"));');
}); });
}); });
describe("sourceMapInline", function() {
it("should append source map to output js when sourceMapInline is enabled", function() {
var result = Uglify.minify('var a = function(foo) { return foo; };', {
fromString: true,
sourceMapInline: true
});
var code = result.code;
assert.strictEqual(code, "var a=function(n){return n};\n" +
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIj8iXSwibmFtZXMiOlsiYSIsImZvbyJdLCJtYXBwaW5ncyI6IkFBQUEsR0FBSUEsR0FBSSxTQUFTQyxHQUFPLE1BQU9BIn0=");
});
it("should not append source map to output js when sourceMapInline is not enabled", function() {
var result = Uglify.minify('var a = function(foo) { return foo; };', {
fromString: true
});
var code = result.code;
assert.strictEqual(code, "var a=function(n){return n};");
});
});
}); });

View File

@@ -44,6 +44,7 @@ exports.minify = function(files, options) {
sourceRoot : null, sourceRoot : null,
inSourceMap : null, inSourceMap : null,
sourceMapUrl : null, sourceMapUrl : null,
sourceMapInline : false,
fromString : false, fromString : false,
warnings : false, warnings : false,
mangle : {}, mangle : {},
@@ -117,7 +118,7 @@ exports.minify = function(files, options) {
if (typeof options.inSourceMap == "string") { if (typeof options.inSourceMap == "string") {
inMap = JSON.parse(fs.readFileSync(options.inSourceMap, "utf8")); inMap = JSON.parse(fs.readFileSync(options.inSourceMap, "utf8"));
} }
if (options.outSourceMap) { if (options.outSourceMap || options.sourceMapInline) {
output.source_map = UglifyJS.SourceMap({ output.source_map = UglifyJS.SourceMap({
file: options.outSourceMap, file: options.outSourceMap,
orig: inMap, orig: inMap,
@@ -138,16 +139,19 @@ exports.minify = function(files, options) {
var stream = UglifyJS.OutputStream(output); var stream = UglifyJS.OutputStream(output);
toplevel.print(stream); toplevel.print(stream);
var mappingUrlPrefix = "\n//# sourceMappingURL=";
if (options.outSourceMap && typeof options.outSourceMap === "string" && options.sourceMapUrl !== false) {
stream += mappingUrlPrefix + (typeof options.sourceMapUrl === "string" ? options.sourceMapUrl : options.outSourceMap);
}
var source_map = output.source_map; var source_map = output.source_map;
if (source_map) { if (source_map) {
source_map = source_map + ""; source_map = source_map + "";
} }
var mappingUrlPrefix = "\n//# sourceMappingURL=";
if (options.sourceMapInline) {
stream += mappingUrlPrefix + "data:application/json;charset=utf-8;base64," + new Buffer(source_map).toString("base64");
} else if (options.outSourceMap && typeof options.outSourceMap === "string" && options.sourceMapUrl !== false) {
stream += mappingUrlPrefix + (typeof options.sourceMapUrl === "string" ? options.sourceMapUrl : options.outSourceMap);
}
return { return {
code : stream + "", code : stream + "",
map : source_map map : source_map