[Pkg-javascript-commits] [uglifyjs] 42/228: allow --in-source-map inline (#1490)

Jonas Smedegaard dr at jones.dk
Sat Apr 15 14:25:15 UTC 2017


This is an automated email from the git hooks/post-receive script.

js pushed a commit to branch master
in repository uglifyjs.

commit cf0951f72635f898ef9dc98ced3c73a1c488cc17
Author: Alex Lam S.L <alexlamsl at gmail.com>
Date:   Sat Feb 25 04:11:21 2017 +0800

    allow --in-source-map inline (#1490)
    
    - limited to one input file (or `stdin`)
    - only works with built-in parser
    
    fixes #520
---
 bin/uglifyjs                   | 71 +++++++++++++++++++++++++++---------------
 test/input/issue-520/input.js  |  3 ++
 test/input/issue-520/output.js |  2 ++
 test/mocha/cli.js              | 48 ++++++++++++++++++++++++++++
 test/mocha/minify.js           | 46 +++++++++++++++++++++++++++
 tools/node.js                  | 31 +++++++++++++++---
 6 files changed, 171 insertions(+), 30 deletions(-)

diff --git a/bin/uglifyjs b/bin/uglifyjs
index 27717fb..d0c3abb 100755
--- a/bin/uglifyjs
+++ b/bin/uglifyjs
@@ -282,21 +282,29 @@ if (ARGS.self) {
 
 var ORIG_MAP = ARGS.in_source_map;
 
-if (ORIG_MAP) {
+if (ORIG_MAP && ORIG_MAP != "inline") {
     ORIG_MAP = JSON.parse(fs.readFileSync(ORIG_MAP));
     if (files.length == 0) {
         print_error("INFO: Using file from the input source map: " + ORIG_MAP.file);
         files = [ ORIG_MAP.file ];
     }
-    if (ARGS.source_map_root == null) {
-        ARGS.source_map_root = ORIG_MAP.sourceRoot;
-    }
 }
 
 if (files.length == 0) {
     files = [ "-" ];
 }
 
+if (ORIG_MAP == "inline") {
+    if (files.length > 1) {
+        print_error("ERROR: Inline source map only works with singular input");
+        process.exit(1);
+    }
+    if (ARGS.acorn || ARGS.spidermonkey) {
+        print_error("ERROR: Inline source map only works with built-in parser");
+        process.exit(1);
+    }
+}
+
 if (files.indexOf("-") >= 0 && ARGS.source_map) {
     print_error("ERROR: Source map doesn't work with input from STDIN");
     process.exit(1);
@@ -308,37 +316,19 @@ if (files.filter(function(el){ return el == "-" }).length > 1) {
 }
 
 var STATS = {};
-var OUTPUT_FILE = ARGS.o;
 var TOPLEVEL = null;
 var P_RELATIVE = ARGS.p && ARGS.p == "relative";
 var SOURCES_CONTENT = {};
 
-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,
-    root: ARGS.source_map_root,
-    orig: ORIG_MAP,
-}) : null;
-
-OUTPUT_OPTIONS.source_map = SOURCE_MAP;
-
-try {
-    var output = UglifyJS.OutputStream(OUTPUT_OPTIONS);
-    var compressor = COMPRESS && UglifyJS.Compressor(COMPRESS);
-} catch(ex) {
-    if (ex instanceof UglifyJS.DefaultsError) {
-        print_error(ex.msg);
-        print_error("Supported options:");
-        print_error(sys.inspect(ex.defs));
-        process.exit(1);
-    }
-}
-
 async.eachLimit(files, 1, function (file, cb) {
     read_whole_file(file, function (err, code) {
         if (err) {
             print_error("ERROR: can't read file: " + file);
             process.exit(1);
         }
+        if (ORIG_MAP == "inline") {
+            ORIG_MAP = read_source_map(code);
+        }
         if (ARGS.p != null) {
             if (P_RELATIVE) {
                 file = path.relative(path.dirname(ARGS.source_map), file).replace(/\\/g, '/');
@@ -385,6 +375,28 @@ async.eachLimit(files, 1, function (file, cb) {
         cb();
     });
 }, function () {
+    var OUTPUT_FILE = ARGS.o;
+
+    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,
+        root: ARGS.source_map_root || ORIG_MAP && ORIG_MAP.sourceRoot,
+        orig: ORIG_MAP,
+    }) : null;
+
+    OUTPUT_OPTIONS.source_map = SOURCE_MAP;
+
+    try {
+        var output = UglifyJS.OutputStream(OUTPUT_OPTIONS);
+        var compressor = COMPRESS && UglifyJS.Compressor(COMPRESS);
+    } catch(ex) {
+        if (ex instanceof UglifyJS.DefaultsError) {
+            print_error(ex.msg);
+            print_error("Supported options:");
+            print_error(sys.inspect(ex.defs));
+            process.exit(1);
+        }
+    }
+
     if (ARGS.acorn || ARGS.spidermonkey) time_it("convert_ast", function(){
         TOPLEVEL = UglifyJS.AST_Node.from_mozilla_ast(TOPLEVEL);
     });
@@ -576,6 +588,15 @@ function read_whole_file(filename, cb) {
     }
 }
 
+function read_source_map(code) {
+    var match = /\n\/\/# sourceMappingURL=data:application\/json(;.*?)?;base64,(.*)/.exec(code);
+    if (!match) {
+        print_error("WARN: inline source map not found");
+        return null;
+    }
+    return JSON.parse(new Buffer(match[2], "base64"));
+}
+
 function time_it(name, cont) {
     var t1 = new Date().getTime();
     var ret = cont();
diff --git a/test/input/issue-520/input.js b/test/input/issue-520/input.js
new file mode 100644
index 0000000..62428a5
--- /dev/null
+++ b/test/input/issue-520/input.js
@@ -0,0 +1,3 @@
+var Foo = function Foo(){console.log(1+2);}; new Foo();
+
+//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjpudWxsLCJzb3VyY2VzIjpbInN0ZGluIl0sInNvdXJjZXNDb250ZW50IjpbImNsYXNzIEZvbyB7IGNvbnN0cnVjdG9yKCl7Y29uc29sZS5sb2coMSsyKTt9IH0gbmV3IEZvbygpO1xuIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLElBQU0sR0FBRyxHQUFDLEFBQUUsWUFBVyxFQUFFLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFBLEFBQUUsQ0FBQyxJQUFJLEdBQUcsRUFBRSxDQUFDOyJ9
diff --git a/test/input/issue-520/output.js b/test/input/issue-520/output.js
new file mode 100644
index 0000000..8d19855
--- /dev/null
+++ b/test/input/issue-520/output.js
@@ -0,0 +1,2 @@
+new function(){console.log(3)};
+//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZGluIl0sIm5hbWVzIjpbImNvbnNvbGUiLCJsb2ciXSwibWFwcGluZ3MiOiJBQUErQyxHQUFyQyxZQUFnQkEsUUFBUUMsSUFBSSIsInNvdXJjZXNDb250ZW50IjpbImNsYXNzIEZvbyB7IGNvbnN0cnVjdG9yKCl7Y29uc29sZS5sb2coMSsyKTt9IH0gbmV3IEZvbygpO1xuIl19
diff --git a/test/mocha/cli.js b/test/mocha/cli.js
index 450df1f..52c7093 100644
--- a/test/mocha/cli.js
+++ b/test/mocha/cli.js
@@ -151,4 +151,52 @@ describe("bin/uglifyjs", function () {
            done();
        });
     });
+    it("Should process inline source map", function(done) {
+        var command = uglifyjscmd + ' test/input/issue-520/input.js -cm toplevel --in-source-map inline --source-map-inline';
+
+        exec(command, function (err, stdout) {
+            if (err) throw err;
+
+            assert.strictEqual(stdout, readFileSync("test/input/issue-520/output.js", "utf8"));
+            done();
+        });
+    });
+    it("Should warn for missing inline source map", function(done) {
+        var command = uglifyjscmd + ' test/input/issue-1323/sample.js --in-source-map inline';
+
+        exec(command, function (err, stdout, stderr) {
+            if (err) throw err;
+
+            assert.strictEqual(stdout, "var bar=function(){function foo(bar){return bar}return foo}();\n");
+            assert.strictEqual(stderr, "WARN: inline source map not found\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 --in-source-map inline --source-map-inline';
+
+        exec(command, function (err, stdout, stderr) {
+            assert.ok(err);
+            assert.strictEqual(stderr, "ERROR: Inline source map only works with singular input\n");
+            done();
+        });
+    });
+    it("Should fail with acorn and inline source map", function(done) {
+        var command = uglifyjscmd + ' test/input/issue-520/input.js --in-source-map inline --source-map-inline --acorn';
+
+        exec(command, function (err, stdout, stderr) {
+            assert.ok(err);
+            assert.strictEqual(stderr, "ERROR: Inline source map only works with built-in parser\n");
+            done();
+        });
+    });
+    it("Should fail with SpiderMonkey and inline source map", function(done) {
+        var command = uglifyjscmd + ' test/input/issue-520/input.js --in-source-map inline --source-map-inline --spidermonkey';
+
+        exec(command, function (err, stdout, stderr) {
+            assert.ok(err);
+            assert.strictEqual(stderr, "ERROR: Inline source map only works with built-in parser\n");
+            done();
+        });
+    });
 });
diff --git a/test/mocha/minify.js b/test/mocha/minify.js
index 8fe1565..1b830cb 100644
--- a/test/mocha/minify.js
+++ b/test/mocha/minify.js
@@ -1,5 +1,6 @@
 var Uglify = require('../../');
 var assert = require("assert");
+var readFileSync = require("fs").readFileSync;
 
 describe("minify", function() {
     it("Should test basic sanity of minify with default options", function() {
@@ -75,6 +76,51 @@ describe("minify", function() {
             assert.equal(map.sourcesContent[0],
                 'let foo = x => "foo " + x;\nconsole.log(foo("bar"));');
         });
+        it("Should process inline source map", function() {
+            var code = Uglify.minify("./test/input/issue-520/input.js", {
+                inSourceMap: "inline",
+                sourceMapInline: true
+            }).code + "\n";
+            assert.strictEqual(code, readFileSync("test/input/issue-520/output.js", "utf8"));
+        });
+        it("Should warn for missing 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("./test/input/issue-1323/sample.js", {
+                    inSourceMap: "inline",
+                    mangle: false,
+                });
+                assert.strictEqual(result.code, "var bar=function(){function foo(bar){return bar}return foo}();");
+                assert.strictEqual(warnings.length, 1);
+                assert.strictEqual(warnings[0], "inline source map not found");
+            } finally {
+                Uglify.AST_Node.warn_function = warn_function;
+            }
+        });
+        it("Should fail with multiple input and inline source map", function() {
+            assert.throws(function() {
+                Uglify.minify([
+                    "./test/input/issue-520/input.js",
+                    "./test/input/issue-520/output.js"
+                ], {
+                    inSourceMap: "inline",
+                    sourceMapInline: true
+                });
+            }, "multiple input and inline source map");
+        });
+        it("Should fail with SpiderMonkey and inline source map", function() {
+            assert.throws(function() {
+                Uglify.minify("./test/input/issue-520/input.js", {
+                    inSourceMap: "inline",
+                    sourceMapInline: true,
+                    spidermonkey: true
+                });
+            }, "SpiderMonkey and inline source map");
+        });
     });
 
     describe("sourceMapInline", function() {
diff --git a/tools/node.js b/tools/node.js
index 108803e..c64b4e5 100644
--- a/tools/node.js
+++ b/tools/node.js
@@ -37,6 +37,15 @@ UglifyJS.AST_Node.warn_function = function(txt) {
     console.error("WARN: %s", txt);
 };
 
+function read_source_map(code) {
+    var match = /\n\/\/# sourceMappingURL=data:application\/json(;.*?)?;base64,(.*)/.exec(code);
+    if (!match) {
+        UglifyJS.AST_Node.warn("inline source map not found");
+        return null;
+    }
+    return JSON.parse(new Buffer(match[2], "base64"));
+}
+
 exports.minify = function(files, options) {
     options = UglifyJS.defaults(options, {
         spidermonkey     : false,
@@ -57,17 +66,28 @@ exports.minify = function(files, options) {
     });
     UglifyJS.base54.reset();
 
+    var inMap = options.inSourceMap;
+    if (typeof inMap == "string" && inMap != "inline") {
+        inMap = JSON.parse(fs.readFileSync(inMap, "utf8"));
+    }
+
     // 1. parse
     var toplevel = null,
         sourcesContent = {};
 
     if (options.spidermonkey) {
+        if (inMap == "inline") {
+            throw new Error("inline source map only works with built-in parser");
+        }
         toplevel = UglifyJS.AST_Node.from_mozilla_ast(files);
     } else {
         function addFile(file, fileUrl) {
             var code = options.fromString
                 ? file
                 : fs.readFileSync(file, "utf8");
+            if (inMap == "inline") {
+                inMap = read_source_map(code);
+            }
             sourcesContent[fileUrl] = code;
             toplevel = UglifyJS.parse(code, {
                 filename: fileUrl,
@@ -75,7 +95,12 @@ exports.minify = function(files, options) {
                 bare_returns: options.parse ? options.parse.bare_returns : undefined
             });
         }
-        if (!options.fromString) files = UglifyJS.simple_glob(files);
+        if (!options.fromString) {
+            files = UglifyJS.simple_glob(files);
+            if (inMap == "inline" && files.length > 1) {
+                throw new Error("inline source map only works with singular input");
+            }
+        }
         [].concat(files).forEach(function (files, i) {
             if (typeof files === 'string') {
                 addFile(files, options.fromString ? i : files);
@@ -114,11 +139,7 @@ exports.minify = function(files, options) {
     }
 
     // 5. output
-    var inMap = options.inSourceMap;
     var output = { max_line_len: 32000 };
-    if (typeof options.inSourceMap == "string") {
-        inMap = JSON.parse(fs.readFileSync(options.inSourceMap, "utf8"));
-    }
     if (options.outSourceMap || options.sourceMapInline) {
         output.source_map = UglifyJS.SourceMap({
             // prefer outFileName, otherwise use outSourceMap without .map suffix

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/uglifyjs.git



More information about the Pkg-javascript-commits mailing list