From 1df9d06f4a6b9116216d8420f5b2ec67f576a301 Mon Sep 17 00:00:00 2001 From: kzc Date: Fri, 19 May 2017 05:20:21 -0400 Subject: [PATCH 1/6] document minify `warnings` and add an error example (#1973) --- README.md | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a7635095..579390ce 100644 --- a/README.md +++ b/README.md @@ -319,9 +319,27 @@ var result = UglifyJS.minify({ console.log(result.code); ``` +To produce warnings: +```javascript +var result = UglifyJS.minify("function f(){ var u; return 5; }", { + warnings: true +}); +console.log(result.code); // function f(){return 5} +console.log(result.warnings); // [ 'Dropping unused variable u [0:1,18]' ] +console.log(result.error); // runtime error, not defined in this case +``` + +An error example: +```javascript +var result = UglifyJS.minify({"foo.js" : "if (0) else console.log(1);"}); +console.log(JSON.stringify(result.error)); +// {"message":"Unexpected token: keyword (else)","filename":"foo.js","line":1,"col":7,"pos":7} +``` + ## Minify options -- `warnings` (default `false`) — pass `true` to display compressor warnings. +- `warnings` (default `false`) — pass `true` to return compressor warnings + in `result.warnings`. Use the value `"verbose"` for more detailed warnings. - `parse` (default `{}`) — pass an object if you wish to specify some additional [parse options](#parse-options). From 5bf8d7e9490155ed6fabea5f1140a87a1e9b596e Mon Sep 17 00:00:00 2001 From: kzc Date: Fri, 19 May 2017 22:49:35 -0400 Subject: [PATCH 2/6] document 3.x minify() does not throw errors (#1975) --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 579390ce..f73bd278 100644 --- a/README.md +++ b/README.md @@ -307,7 +307,7 @@ Example: ```javascript var result = UglifyJS.minify("var b = function() {};"); console.log(result.code); // minified output -console.log(result.error); // runtime error +console.log(result.error); // runtime error, if present ``` You can also compress multiple files: @@ -335,6 +335,12 @@ var result = UglifyJS.minify({"foo.js" : "if (0) else console.log(1);"}); console.log(JSON.stringify(result.error)); // {"message":"Unexpected token: keyword (else)","filename":"foo.js","line":1,"col":7,"pos":7} ``` +Note: unlike `uglify-js@2.x`, the `3.x` API does not throw errors. To +achieve a similar effect one could do the following: +```javascript +var result = UglifyJS.minify("if (0) else console.log(1);"); +if (result.error) throw result.error; +``` ## Minify options From 58fae7dc070449e650d1a48ad7144cb5571a510f Mon Sep 17 00:00:00 2001 From: "Alex Lam S.L" Date: Sat, 20 May 2017 15:58:46 +0800 Subject: [PATCH 3/6] enhance `if_return` to handle `return void...` (#1977) fixes #512 --- lib/compress.js | 19 ++++++++++--------- test/compress/if_return.js | 22 ++++++++++++++++++++++ test/mocha/cli.js | 4 +++- test/mocha/spidermonkey.js | 4 +++- 4 files changed, 38 insertions(+), 11 deletions(-) diff --git a/lib/compress.js b/lib/compress.js index f6bf3d05..73ab21f4 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -914,12 +914,12 @@ merge(Compressor.prototype, { continue loop; case stat instanceof AST_If: if (stat.body instanceof AST_Return) { + var value = stat.body.value; //--- // pretty silly case, but: // if (foo()) return; return; ==> foo(); return; - if (((in_lambda && ret.length == 0) - || (ret[0] instanceof AST_Return && !ret[0].value)) - && !stat.body.value && !stat.alternative) { + if ((in_lambda && ret.length == 0 || ret[0] instanceof AST_Return && !ret[0].value) + && !value && !stat.alternative) { CHANGED = true; var cond = make_node(AST_SimpleStatement, stat.condition, { body: stat.condition @@ -929,7 +929,7 @@ merge(Compressor.prototype, { } //--- // if (foo()) return x; return y; ==> return foo() ? x : y; - if (ret[0] instanceof AST_Return && stat.body.value && ret[0].value && !stat.alternative) { + if (ret[0] instanceof AST_Return && value && ret[0].value && !stat.alternative) { CHANGED = true; stat = stat.clone(); stat.alternative = ret[0]; @@ -939,7 +939,7 @@ merge(Compressor.prototype, { //--- // if (foo()) return x; [ return ; ] ==> return foo() ? x : undefined; if (multiple_if_returns && (ret.length == 0 || ret[0] instanceof AST_Return) - && stat.body.value && !stat.alternative && in_lambda) { + && value && !stat.alternative && in_lambda) { CHANGED = true; stat = stat.clone(); stat.alternative = ret[0] || make_node(AST_Return, stat, { @@ -949,8 +949,8 @@ merge(Compressor.prototype, { continue loop; } //--- - // if (foo()) return; [ else x... ]; y... ==> if (!foo()) { x...; y... } - if (!stat.body.value && in_lambda) { + // if (foo()) return [ void bar() ]; [ else x...; ] y... ==> if (!foo()) { x...; y... } else bar(); + if (in_lambda && (!value || value instanceof AST_UnaryPrefix && value.operator == "void")) { CHANGED = true; stat = stat.clone(); stat.condition = stat.condition.negate(compressor); @@ -959,11 +959,12 @@ merge(Compressor.prototype, { stat.body = make_node(AST_BlockStatement, stat, { body: body }); - stat.alternative = null; + stat.alternative = value ? make_node(AST_SimpleStatement, value, { + body: value.expression + }) : null; ret = funs.concat([ stat.transform(compressor) ]); continue loop; } - //--- // if (a) return b; if (c) return d; e; ==> return a ? b : c ? d : void e; // diff --git a/test/compress/if_return.js b/test/compress/if_return.js index 0ac45c3c..c09d67b6 100644 --- a/test/compress/if_return.js +++ b/test/compress/if_return.js @@ -302,3 +302,25 @@ issue_1437_conditionals: { } } } + +issue_512: { + options = { + conditionals: true, + if_return: true, + } + input: { + function a() { + if (b()) { + c(); + return; + } + throw e; + } + } + expect: { + function a() { + if (!b()) throw e; + c(); + } + } +} diff --git a/test/mocha/cli.js b/test/mocha/cli.js index 335b224d..db4a2c33 100644 --- a/test/mocha/cli.js +++ b/test/mocha/cli.js @@ -19,7 +19,9 @@ describe("bin/uglifyjs", function () { eval(stdout); assert.strictEqual(typeof WrappedUglifyJS, 'object'); - assert.strictEqual(WrappedUglifyJS.minify("foo([true,,2+3]);").code, "foo([!0,,5]);"); + var result = WrappedUglifyJS.minify("foo([true,,2+3]);"); + assert.strictEqual(result.error, undefined); + assert.strictEqual(result.code, "foo([!0,,5]);"); done(); }); diff --git a/test/mocha/spidermonkey.js b/test/mocha/spidermonkey.js index a8a112d0..9bddb537 100644 --- a/test/mocha/spidermonkey.js +++ b/test/mocha/spidermonkey.js @@ -15,7 +15,9 @@ describe("spidermonkey export/import sanity test", function() { eval(stdout); assert.strictEqual(typeof SpiderUglify, "object"); - assert.strictEqual(SpiderUglify.minify("foo([true,,2+3]);").code, "foo([!0,,5]);"); + var result = SpiderUglify.minify("foo([true,,2+3]);"); + assert.strictEqual(result.error, undefined); + assert.strictEqual(result.code, "foo([!0,,5]);"); done(); }); From 22aedef849e6e1ee8fd8c8ed0ccf27127eccd10a Mon Sep 17 00:00:00 2001 From: kzc Date: Sat, 20 May 2017 10:09:21 -0400 Subject: [PATCH 4/6] document minify() option `toplevel` (#1979) --- README.md | 53 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index f73bd278..2c6ee374 100644 --- a/README.md +++ b/README.md @@ -301,32 +301,45 @@ like this: var UglifyJS = require("uglify-js"); ``` -There is a single high level minification function, `minify(files, options)`, which will +There is a single high level minification function, `minify(code, options)`, which will performs all the steps in a configurable manner. Example: ```javascript -var result = UglifyJS.minify("var b = function() {};"); -console.log(result.code); // minified output -console.log(result.error); // runtime error, if present +var code = "function add(first, second) { return first + second; }"; +var result = UglifyJS.minify(code); +console.log(result.error); // runtime error, or `undefined` if no error +console.log(result.code); // minified output: function add(n,d){return n+d} ``` You can also compress multiple files: ```javascript -var result = UglifyJS.minify({ - "file1.js": "var a = function() {};", - "file2.js": "var b = function() {};" -}); -console.log(result.code); +var code = { + "file1.js": "function add(first, second) { return first + second; }", + "file2.js": "console.log(add(1 + 2, 3 + 4));" +}; +var result = UglifyJS.minify(code); +console.log(result.code); // function add(d,n){return d+n}console.log(add(3,7)); +``` + +The `toplevel` option: +```javascript +var code = { + "file1.js": "function add(first, second) { return first + second; }", + "file2.js": "console.log(add(1 + 2, 3 + 4));" +}; +var options = { toplevel: true }; +var result = UglifyJS.minify(code, options); +console.log(result.code); // console.log(function(n,o){return n+o}(3,7)); ``` To produce warnings: ```javascript -var result = UglifyJS.minify("function f(){ var u; return 5; }", { - warnings: true -}); -console.log(result.code); // function f(){return 5} +var code = "function f(){ var u; return 2 + 3; }"; +var options = { warnings: true }; +var result = UglifyJS.minify(code, options); +console.log(result.error); // runtime error, `undefined` in this case console.log(result.warnings); // [ 'Dropping unused variable u [0:1,18]' ] -console.log(result.error); // runtime error, not defined in this case +console.log(result.code); // function f(){return 5} ``` An error example: @@ -338,7 +351,7 @@ console.log(JSON.stringify(result.error)); Note: unlike `uglify-js@2.x`, the `3.x` API does not throw errors. To achieve a similar effect one could do the following: ```javascript -var result = UglifyJS.minify("if (0) else console.log(1);"); +var result = UglifyJS.minify(code, options); if (result.error) throw result.error; ``` @@ -371,7 +384,7 @@ if (result.error) throw result.error; - `ie8` (default `false`) - set to `true` to support IE8. -## Minify option structure +## Minify options structure ```javascript { @@ -526,8 +539,8 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u - `cascade` -- small optimization for sequences, transform `x, x` into `x` and `x = something(), x` into `x = something()` -- `collapse_vars` -- Collapse single-use `var` and `const` definitions - when possible. +- `collapse_vars` -- Collapse single-use non-constant variables - side + effects permitting. - `reduce_vars` -- Improve optimization on variables assigned with and used as constant values. @@ -749,8 +762,8 @@ Another way of doing that is to declare your globals as constants in a separate file and include it into the build. For example you can have a `build/defines.js` file with the following: ```javascript -const DEBUG = false; -const PRODUCTION = true; +var DEBUG = false; +var PRODUCTION = true; // etc. ``` From 7e164aba8f9cc295b9e251cbe800f47c6390b0be Mon Sep 17 00:00:00 2001 From: kzc Date: Sat, 20 May 2017 10:09:51 -0400 Subject: [PATCH 5/6] add "es5" to package.json keywords (#1980) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4bd70c4b..088a2926 100644 --- a/package.json +++ b/package.json @@ -40,5 +40,5 @@ "scripts": { "test": "node test/run-tests.js" }, - "keywords": ["uglify", "uglify-js", "minify", "minifier"] + "keywords": ["uglify", "uglify-js", "minify", "minifier", "es5"] } From d3c4a8e9e705af2c90b940b0053dad222a45ed34 Mon Sep 17 00:00:00 2001 From: "Alex Lam S.L" Date: Sun, 21 May 2017 01:30:17 +0800 Subject: [PATCH 6/6] v3.0.10 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 088a2926..b40066c0 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "homepage": "http://lisperator.net/uglifyjs", "author": "Mihai Bazon (http://lisperator.net/)", "license": "BSD-2-Clause", - "version": "3.0.9", + "version": "3.0.10", "engines": { "node": ">=0.8.0" },