diff --git a/README.md b/README.md index fd1bfef1..7a3e961c 100644 --- a/README.md +++ b/README.md @@ -118,6 +118,7 @@ The available options are: code relying on Function.prototype.name. --self Build UglifyJS2 as a library (implies --wrap UglifyJS) --source-map [options] Enable source map/specify source map options: + `base` Path to compute relative paths from input files. `content` Input source map, useful if you're compressing JS that was generated from some other original code. Specify "inline" if the source map is @@ -146,17 +147,6 @@ TODOs: --reserved-file File containing reserved names --reserve-domprops Make (most?) DOM properties reserved for --mangle-props - --mangle-props Mangle property names (default `0`). Set to - `true` or `1` to mangle all property names. Set - to `unquoted` or `2` to only mangle unquoted - property names. Mode `2` also enables the - `keep_quoted_props` beautifier option to - preserve the quotes around property names and - disables the `properties` compressor option to - prevent rewriting quoted properties with dot - notation. You can override these by setting - them explicitly on the command line. - --mangle-regex Only mangle property names matching the regex --name-cache File to hold mangled names mappings ``` @@ -167,23 +157,19 @@ goes to STDOUT. UglifyJS2 can generate a source map file, which is highly useful for debugging your compressed JavaScript. To get a source map, pass -`--source-map output.js.map` (full path to the file where you want the -source map dumped). +`--source-map --output output.js` (source map will be written out to +`output.js.map`). -Additionally you might need `--source-map-root` to pass the URL where the -original files can be found. In case you are passing full paths to input -files to UglifyJS, you can use `--prefix` (`-p`) to specify the number of -directories to drop from the path prefix when declaring files in the source -map. +Additionally you might need `--source-map root=` to pass the URL where +the original files can be found. Use `--source-map url=` to specify +the URL where the source map can be found. For example: uglifyjs /home/doe/work/foo/src/js/file1.js \ /home/doe/work/foo/src/js/file2.js \ - -o foo.min.js \ - --source-map foo.min.js.map \ - --source-map-root http://foo.com/src \ - -p 5 -c -m + -o foo.min.js -c -m \ + --source-map base="/home/doe/work/foo/src",root="http://foo.com/src" The above will compress and mangle `file1.js` and `file2.js`, will drop the output in `foo.min.js` and the source map in `foo.min.js.map`. The source @@ -273,8 +259,8 @@ cover most standard JS and DOM properties defined in various browsers. Pass `--reserve-domprops` to read that in. You can also use a regular expression to define which property names should be -mangled. For example, `--mangle-regex="/^_/"` will only mangle property names -that start with an underscore. +mangled. For example, `--mangle-props regex=/^_/` will only mangle property +names that start with an underscore. When you compress multiple files using this option, in order for them to work together in the end we need to ensure somehow that one property gets @@ -294,26 +280,26 @@ of mangled property names. Using the name cache is not necessary if you compress all your files in a single call to UglifyJS. -#### Mangling unquoted names (`--mangle-props=unquoted` or `--mangle-props=2`) +#### Mangling unquoted names (`--mangle-props ignore_quoted`) Using quoted property name (`o["foo"]`) reserves the property name (`foo`) so that it is not mangled throughout the entire script even when used in an unquoted style (`o.foo`). Example: ``` -$ echo 'var o={"foo":1, bar:3}; o.foo += o.bar; console.log(o.foo);' | uglifyjs --mangle-props=2 -mc -var o={"foo":1,a:3};o.foo+=o.a,console.log(o.foo); +$ echo 'var o={"foo":1, bar:3}; o.foo += o.bar; console.log(o.foo);' | uglifyjs --mangle-props ignore_quoted -mc +var o={foo:1,a:3};o.foo+=o.a,console.log(o.foo); ``` #### Debugging property name mangling -You can also pass `--mangle-props-debug` in order to mangle property names +You can also pass `--mangle-props debug` in order to mangle property names without completely obscuring them. For example the property `o.foo` would mangle to `o._$foo$_` with this option. This allows property mangling of a large codebase while still being able to debug the code and identify where mangling is breaking things. -You can also pass a custom suffix using `--mangle-props-debug=XYZ`. This would then +You can also pass a custom suffix using `--mangle-props debug=XYZ`. This would then mangle `o.foo` to `o._$foo$XYZ_`. You can change this each time you compile a script to identify how a property got mangled. One technique is to pass a random number on every compile to simulate mangling changing with different @@ -674,7 +660,7 @@ Example: var result = UglifyJS.minify("/path/to/file.js"); console.log(result.code); // minified output // if you need to pass code instead of file name -var result = UglifyJS.minify("var b = function () {};", {fromString: true}); +var result = UglifyJS.minify("var b = function() {};", {fromString: true}); ``` You can also compress multiple files: @@ -694,7 +680,7 @@ console.log(result.map); To generate a source map with the fromString option, you can also use an object: ```javascript -var result = UglifyJS.minify({"file1.js": "var a = function () {};"}, { +var result = UglifyJS.minify({"file1.js": "var a = function() {};"}, { outSourceMap: "out.js.map", outFileName: "out.js", fromString: true diff --git a/bin/uglifyjs b/bin/uglifyjs index a4870e66..a3925bd4 100755 --- a/bin/uglifyjs +++ b/bin/uglifyjs @@ -85,6 +85,18 @@ if (program.parse) { options.parse = program.parse; } } +var convert_path = function(name) { + return name; +}; +if (program.sourceMap && "base" in program.sourceMap) { + convert_path = function() { + var base = program.sourceMap.base; + delete options.sourceMap.base; + return function(name) { + return path.relative(base, name); + }; + }(); +} if (program.verbose && options.compress) { if (typeof options.compress != "object") options.compress = {}; options.compress.warnings = "verbose"; @@ -94,21 +106,21 @@ if (program.self) { console.error("WARN: Ignoring input files since --self was passed"); } if (!options.wrap) options.wrap = "UglifyJS"; - simple_glob(UglifyJS.FILES).forEach(function(path) { - files[path] = readFile(path); + simple_glob(UglifyJS.FILES).forEach(function(name) { + files[convert_path(name)] = readFile(name); }); run(); } else if (program.args.length) { - simple_glob(program.args).forEach(function(path) { - files[path] = readFile(path); + simple_glob(program.args).forEach(function(name) { + files[convert_path(name)] = readFile(name); }); run(); } else { var chunks = []; process.stdin.setEncoding("utf8"); - process.stdin.on("data", function (chunk) { + process.stdin.on("data", function(chunk) { chunks.push(chunk); - }).on("end", function () { + }).on("end", function() { files = [ chunks.join("") ]; run(); }); diff --git a/lib/ast.js b/lib/ast.js index a3b32390..0fa051b8 100644 --- a/lib/ast.js +++ b/lib/ast.js @@ -880,7 +880,7 @@ TreeWalker.prototype = { parent: function(n) { return this.stack[this.stack.length - 2 - (n || 0)]; }, - push: function (node) { + push: function(node) { if (node instanceof AST_Lambda) { this.directives = Object.create(this.directives); } else if (node instanceof AST_Directive && !this.directives[node.value]) { diff --git a/lib/compress.js b/lib/compress.js index 26433840..d4983d0e 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -1216,7 +1216,7 @@ merge(Compressor.prototype, { /* -----[ boolean/negation helpers ]----- */ // methods to determine whether an expression has a boolean result type - (function (def){ + (function(def){ var unary_bool = [ "!", "delete" ]; var binary_bool = [ "in", "instanceof", "==", "!=", "===", "!==", "<", "<=", ">=", ">" ]; def(AST_Node, return_false); @@ -1244,7 +1244,7 @@ merge(Compressor.prototype, { }); // methods to determine if an expression has a numeric result type - (function (def){ + (function(def){ def(AST_Node, return_false); def(AST_Number, return_true); var unary = makePredicate("+ - ~ ++ --"); @@ -1272,7 +1272,7 @@ merge(Compressor.prototype, { }); // methods to determine if an expression has a string result type - (function (def){ + (function(def){ def(AST_Node, return_false); def(AST_String, return_true); def(AST_UnaryPrefix, function(){ @@ -1302,7 +1302,7 @@ merge(Compressor.prototype, { if (parent instanceof AST_Assign && parent.left === node) return node; } - (function (def){ + (function(def){ AST_Node.DEFMETHOD("resolve_defines", function(compressor) { if (!compressor.option("global_defs")) return; var def = this._find_defs(compressor, ""); @@ -1383,7 +1383,7 @@ merge(Compressor.prototype, { } // methods to evaluate a constant expression - (function (def){ + (function(def){ // If the node has been successfully reduced to a constant, // then its value is returned; otherwise the element itself // is returned. diff --git a/lib/output.js b/lib/output.js index e2308370..7a2e850f 100644 --- a/lib/output.js +++ b/lib/output.js @@ -681,7 +681,7 @@ function OutputStream(options) { } }); - PARENS([ AST_Assign, AST_Conditional ], function (output){ + PARENS([ AST_Assign, AST_Conditional ], function(output){ var p = output.parent(); // !(a = false) → true if (p instanceof AST_Unary) diff --git a/test/mocha/spidermonkey.js b/test/mocha/spidermonkey.js index f7489c96..e5bf45a2 100644 --- a/test/mocha/spidermonkey.js +++ b/test/mocha/spidermonkey.js @@ -3,14 +3,14 @@ var exec = require("child_process").exec; var uglify = require("../../"); describe("spidermonkey export/import sanity test", function() { - it("should produce a functional build when using --self with spidermonkey", function (done) { + it("should produce a functional build when using --self with spidermonkey", function(done) { this.timeout(20000); var uglifyjs = '"' + process.argv[0] + '" bin/uglifyjs'; var command = uglifyjs + " --self -cm --wrap SpiderUglify -o spidermonkey | " + uglifyjs + " -p spidermonkey -cm"; - exec(command, function (err, stdout) { + exec(command, function(err, stdout) { if (err) throw err; eval(stdout);