Compare commits

...

6 Commits

Author SHA1 Message Date
Alex Lam S.L
90585e29c2 v3.3.15 2018-03-14 16:45:38 +00:00
Alex Lam S.L
d8fc281915 update dependencies (#3002)
acorn 5.5.3
commander 2.15.0

Miscellaneous
- drop unmaintained package from README
2018-03-14 15:54:41 +08:00
Alex Lam S.L
188c39e8d5 retain comments within brackets (#2999)
fixes #2998
2018-03-13 18:44:21 +08:00
Alex Lam S.L
5429234138 preserve non-constant value assignments with modifications (#2997)
fixes #2995
2018-03-13 17:35:34 +08:00
Alex Lam S.L
b9f72a4a81 handle case correctly under reduce_vars (#2993)
fixes #2992
2018-03-11 15:54:43 +08:00
Alex Lam S.L
fc6ebd04a5 preserve case when inline_script (#2991)
fixes #2989
2018-03-11 05:11:12 +08:00
9 changed files with 182 additions and 29 deletions

View File

@@ -6,9 +6,8 @@ UglifyJS is a JavaScript parser, minifier, compressor and beautifier toolkit.
#### Note: #### Note:
- **`uglify-js@3` has a simplified [API](#api-reference) and [CLI](#command-line-usage) that is not backwards compatible with [`uglify-js@2`](https://github.com/mishoo/UglifyJS2/tree/v2.x)**. - **`uglify-js@3` has a simplified [API](#api-reference) and [CLI](#command-line-usage) that is not backwards compatible with [`uglify-js@2`](https://github.com/mishoo/UglifyJS2/tree/v2.x)**.
- **Documentation for UglifyJS `2.x` releases can be found [here](https://github.com/mishoo/UglifyJS2/tree/v2.x)**. - **Documentation for UglifyJS `2.x` releases can be found [here](https://github.com/mishoo/UglifyJS2/tree/v2.x)**.
- `uglify-js` only supports ECMAScript 5 (ES5). - `uglify-js` only supports JavaScript (ECMAScript 5).
- Those wishing to minify - To minify ECMAScript 2015 or above, transpile using tools like [Babel](https://babeljs.io/).
ES2015+ (ES6+) should use the `npm` package [**uglify-es**](https://github.com/mishoo/UglifyJS2/tree/harmony).
Install Install
------- -------
@@ -837,8 +836,8 @@ can pass additional arguments that control the code output:
- `indent_start` (default `0`) -- prefix all lines by that many spaces - `indent_start` (default `0`) -- prefix all lines by that many spaces
- `inline_script` (default `false`) -- escape the slash in occurrences of - `inline_script` (default `true`) -- escape HTML comments and the slash in
`</script` in strings occurrences of `</script>` in strings
- `keep_quoted_props` (default `false`) -- when turned on, prevents stripping - `keep_quoted_props` (default `false`) -- when turned on, prevents stripping
quotes from property names in object literals. quotes from property names in object literals.

View File

@@ -517,6 +517,15 @@ merge(Compressor.prototype, {
pop(tw); pop(tw);
return true; return true;
}); });
def(AST_Case, function(tw) {
push(tw);
this.expression.walk(tw);
pop(tw);
push(tw);
walk_body(this, tw);
pop(tw);
return true;
});
def(AST_Conditional, function(tw) { def(AST_Conditional, function(tw) {
this.condition.walk(tw); this.condition.walk(tw);
push(tw); push(tw);
@@ -527,6 +536,12 @@ merge(Compressor.prototype, {
pop(tw); pop(tw);
return true; return true;
}); });
def(AST_Default, function(tw, descend) {
push(tw);
descend();
pop(tw);
return true;
});
def(AST_Defun, function(tw, descend, compressor) { def(AST_Defun, function(tw, descend, compressor) {
this.inlined = false; this.inlined = false;
var save_ids = tw.safe_ids; var save_ids = tw.safe_ids;
@@ -624,12 +639,6 @@ merge(Compressor.prototype, {
pop(tw); pop(tw);
return true; return true;
}); });
def(AST_SwitchBranch, function(tw, descend) {
push(tw);
descend();
pop(tw);
return true;
});
def(AST_SymbolCatch, function() { def(AST_SymbolCatch, function() {
this.definition().fixed = false; this.definition().fixed = false;
}); });
@@ -3105,6 +3114,8 @@ merge(Compressor.prototype, {
var in_use = []; var in_use = [];
var in_use_ids = Object.create(null); // avoid expensive linear scans of in_use var in_use_ids = Object.create(null); // avoid expensive linear scans of in_use
var fixed_ids = Object.create(null); var fixed_ids = Object.create(null);
var value_read = Object.create(null);
var value_modified = Object.create(null);
if (self instanceof AST_Toplevel && compressor.top_retain) { if (self instanceof AST_Toplevel && compressor.top_retain) {
self.variables.each(function(def) { self.variables.each(function(def) {
if (compressor.top_retain(def) && !(def.id in in_use_ids)) { if (compressor.top_retain(def) && !(def.id in in_use_ids)) {
@@ -3372,6 +3383,17 @@ merge(Compressor.prototype, {
); );
self.transform(tt); self.transform(tt);
function verify_safe_usage(def, read, modified) {
if (def.id in in_use_ids) return;
if (read && modified) {
in_use_ids[def.id] = true;
in_use.push(def);
} else {
value_read[def.id] = read;
value_modified[def.id] = modified;
}
}
function scan_ref_scoped(node, descend) { function scan_ref_scoped(node, descend) {
var node_def, props = [], sym = assign_as_unused(node, props); var node_def, props = [], sym = assign_as_unused(node, props);
if (sym instanceof AST_SymbolRef if (sym instanceof AST_SymbolRef
@@ -3381,9 +3403,19 @@ merge(Compressor.prototype, {
}); });
if (node instanceof AST_Assign) { if (node instanceof AST_Assign) {
node.right.walk(tw); node.right.walk(tw);
if (node.left === sym && !node_def.chained && sym.fixed_value() === node.right) { if (node.left === sym) {
if (!node_def.chained && sym.fixed_value() === node.right) {
fixed_ids[node_def.id] = node; fixed_ids[node_def.id] = node;
} }
if (!node.write_only) {
verify_safe_usage(node_def, true, value_modified[node_def.id]);
}
} else {
var fixed = sym.fixed_value();
if (!fixed || !fixed.is_constant()) {
verify_safe_usage(node_def, value_read[node_def.id], true);
}
}
} }
return true; return true;
} }

View File

@@ -178,7 +178,7 @@ function OutputStream(options) {
function encode_string(str, quote) { function encode_string(str, quote) {
var ret = make_string(str, quote); var ret = make_string(str, quote);
if (options.inline_script) { if (options.inline_script) {
ret = ret.replace(/<\x2fscript([>\/\t\n\f\r ])/gi, "<\\/script$1"); ret = ret.replace(/<\x2f(script)([>\/\t\n\f\r ])/gi, "<\\/$1$2");
ret = ret.replace(/\x3c!--/g, "\\x3c!--"); ret = ret.replace(/\x3c!--/g, "\\x3c!--");
ret = ret.replace(/--\x3e/g, "--\\x3e"); ret = ret.replace(/--\x3e/g, "--\\x3e");
} }
@@ -886,18 +886,19 @@ function OutputStream(options) {
self.body.print(output); self.body.print(output);
output.semicolon(); output.semicolon();
}); });
function print_bracketed(self, output, allow_directives) { function print_bracketed_empty(self, output) {
if (self.body.length > 0) {
output.with_block(function() {
display_body(self.body, false, output, allow_directives);
});
} else {
output.print("{"); output.print("{");
output.with_indent(output.next_indent(), function() { output.with_indent(output.next_indent(), function() {
output.append_comments(self, true); output.append_comments(self, true);
}); });
output.print("}"); output.print("}");
} }
function print_bracketed(self, output, allow_directives) {
if (self.body.length > 0) {
output.with_block(function() {
display_body(self.body, false, output, allow_directives);
});
} else print_bracketed_empty(self, output);
}; };
DEFPRINT(AST_BlockStatement, function(self, output){ DEFPRINT(AST_BlockStatement, function(self, output){
print_bracketed(self, output); print_bracketed(self, output);
@@ -1092,7 +1093,7 @@ function OutputStream(options) {
}); });
output.space(); output.space();
var last = self.body.length - 1; var last = self.body.length - 1;
if (last < 0) output.print("{}"); if (last < 0) print_bracketed_empty(self, output);
else output.with_block(function(){ else output.with_block(function(){
self.body.forEach(function(branch, i){ self.body.forEach(function(branch, i){
output.indent(true); output.indent(true);
@@ -1347,7 +1348,7 @@ function OutputStream(options) {
}); });
output.newline(); output.newline();
}); });
else output.print("{}"); else print_bracketed_empty(self, output);
}); });
function print_property_name(key, quote, output) { function print_property_name(key, quote, output) {

View File

@@ -1,10 +1,9 @@
{ {
"name": "uglify-js", "name": "uglify-js",
"description": "JavaScript parser, mangler/compressor and beautifier toolkit", "description": "JavaScript parser, mangler/compressor and beautifier toolkit",
"homepage": "http://lisperator.net/uglifyjs",
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)", "author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
"license": "BSD-2-Clause", "license": "BSD-2-Clause",
"version": "3.3.14", "version": "3.3.15",
"engines": { "engines": {
"node": ">=0.8.0" "node": ">=0.8.0"
}, },
@@ -24,16 +23,39 @@
"LICENSE" "LICENSE"
], ],
"dependencies": { "dependencies": {
"commander": "~2.14.1", "commander": "~2.15.0",
"source-map": "~0.6.1" "source-map": "~0.6.1"
}, },
"devDependencies": { "devDependencies": {
"acorn": "~5.4.1", "acorn": "~5.5.3",
"mocha": "~3.5.1", "mocha": "~3.5.1",
"semver": "~5.5.0" "semver": "~5.5.0"
}, },
"scripts": { "scripts": {
"test": "node test/run-tests.js" "test": "node test/run-tests.js"
}, },
"keywords": ["uglify", "uglify-js", "minify", "minifier", "es5"] "keywords": [
"cli",
"compress",
"compressor",
"ecma",
"ecmascript",
"es",
"es5",
"javascript",
"js",
"jsmin",
"min",
"minification",
"minifier",
"minify",
"optimize",
"optimizer",
"pack",
"packer",
"parse",
"parser",
"uglifier",
"uglify"
]
} }

View File

@@ -1785,3 +1785,32 @@ issue_805_2: {
"bar", "bar",
] ]
} }
issue_2995: {
options = {
pure_getters: "strict",
reduce_vars: true,
unused: true,
}
input: {
function f(a) {
var b;
a.b = b = function() {};
b.c = "PASS";
}
var o = {};
f(o);
console.log(o.b.c);
}
expect: {
function f(a) {
var b;
a.b = b = function() {};
b.c = "PASS";
}
var o = {};
f(o);
console.log(o.b.c);
}
expect_stdout: "PASS"
}

View File

@@ -0,0 +1,21 @@
inline_script_off: {
beautify = {
inline_script: false,
}
input: {
console.log("</sCrIpT>");
}
expect_exact: 'console.log("</sCrIpT>");'
expect_stdout: "</sCrIpT>"
}
inline_script_on: {
beautify = {
inline_script: true,
}
input: {
console.log("</sCrIpT>");
}
expect_exact: 'console.log("<\\/sCrIpT>");'
expect_stdout: "</sCrIpT>"
}

View File

@@ -5545,3 +5545,33 @@ issue_2919: {
} }
expect_stdout: "function" expect_stdout: "function"
} }
issue_2992: {
options = {
evaluate: true,
reduce_vars: true,
}
input: {
var c = "PASS";
(function f(b) {
switch (0) {
case 0:
case b = 1:
b && (c = "FAIL");
}
})();
console.log(c);
}
expect: {
var c = "PASS";
(function f(b) {
switch (0) {
case 0:
case b = 1:
b && (c = "FAIL");
}
})();
console.log(c);
}
expect_stdout: "PASS"
}

View File

@@ -139,6 +139,26 @@ describe("Comment", function() {
assert.strictEqual(result.code, code); assert.strictEqual(result.code, code);
}); });
it("Should retain comments within brackets", function() {
var code = [
"{/* foo */}",
"a({/* foo */});",
"while (a) {/* foo */}",
"switch (a) {/* foo */}",
"if (a) {/* foo */} else {/* bar */}",
].join("\n\n");
var result = uglify.minify(code, {
compress: false,
mangle: false,
output: {
beautify: true,
comments: "all",
},
});
if (result.error) throw result.error;
assert.strictEqual(result.code, code);
});
it("Should correctly preserve new lines around comments", function() { it("Should correctly preserve new lines around comments", function() {
var tests = [ var tests = [
[ [

View File

@@ -343,7 +343,6 @@ function parse_test(file) {
} }
function make_code(ast, options) { function make_code(ast, options) {
options.inline_script = true;
var stream = U.OutputStream(options); var stream = U.OutputStream(options);
ast.print(stream); ast.print(stream);
return stream.get(); return stream.get();