Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
90585e29c2 | ||
|
|
d8fc281915 | ||
|
|
188c39e8d5 | ||
|
|
5429234138 | ||
|
|
b9f72a4a81 | ||
|
|
fc6ebd04a5 |
@@ -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.
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
32
package.json
32
package.json
@@ -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"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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"
|
||||||
|
}
|
||||||
|
|||||||
21
test/compress/issue-2989.js
Normal file
21
test/compress/issue-2989.js
Normal 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>"
|
||||||
|
}
|
||||||
@@ -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"
|
||||||
|
}
|
||||||
|
|||||||
@@ -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 = [
|
||||||
[
|
[
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
Reference in New Issue
Block a user