Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5fd8244a2e | ||
|
|
c14e280585 | ||
|
|
bc3fa78e8c | ||
|
|
8c7c107765 | ||
|
|
3dd328dce3 | ||
|
|
014f428153 | ||
|
|
a3b2eb75bd | ||
|
|
da295de82b | ||
|
|
4f8ca4626e | ||
|
|
e54748365c | ||
|
|
2d99d06601 | ||
|
|
98cf95e5b5 |
23
README.md
23
README.md
@@ -42,8 +42,7 @@ in sequence and apply any compression options. The files are parsed in the
|
|||||||
same global scope, that is, a reference from a file to some
|
same global scope, that is, a reference from a file to some
|
||||||
variable/function declared in another file will be matched properly.
|
variable/function declared in another file will be matched properly.
|
||||||
|
|
||||||
If you want to read from STDIN instead, pass a single dash instead of input
|
If no input file is specified, UglifyJS will read from STDIN.
|
||||||
files.
|
|
||||||
|
|
||||||
If you wish to pass your options before the input files, separate the two with
|
If you wish to pass your options before the input files, separate the two with
|
||||||
a double dash to prevent input files being used as option arguments:
|
a double dash to prevent input files being used as option arguments:
|
||||||
@@ -96,8 +95,9 @@ The available options are:
|
|||||||
`wrap_iife` Wrap IIFEs in parenthesis. Note: you may
|
`wrap_iife` Wrap IIFEs in parenthesis. Note: you may
|
||||||
want to disable `negate_iife` under
|
want to disable `negate_iife` under
|
||||||
compressor options.
|
compressor options.
|
||||||
-o, --output <file> Output file (default STDOUT). Specify "spidermonkey"
|
-o, --output <file> Output file path (default STDOUT). Specify `ast` or
|
||||||
to dump SpiderMonkey AST format (as JSON) to STDOUT.
|
`spidermonkey` to write UglifyJS or SpiderMonkey AST
|
||||||
|
as JSON to STDOUT respectively.
|
||||||
--comments [filter] Preserve copyright comments in the output. By
|
--comments [filter] Preserve copyright comments in the output. By
|
||||||
default this works like Google Closure, keeping
|
default this works like Google Closure, keeping
|
||||||
JSDoc-style comments that contain "@license" or
|
JSDoc-style comments that contain "@license" or
|
||||||
@@ -490,21 +490,21 @@ can pass additional arguments that control the code output:
|
|||||||
Passing `-b` will set this to true, but you might need to pass `-b` even
|
Passing `-b` will set this to true, but you might need to pass `-b` even
|
||||||
when you want to generate minified code, in order to specify additional
|
when you want to generate minified code, in order to specify additional
|
||||||
arguments, so you can use `-b beautify=false` to override it.
|
arguments, so you can use `-b beautify=false` to override it.
|
||||||
- `indent-level` (default 4)
|
- `indent_level` (default 4)
|
||||||
- `indent-start` (default 0) -- prefix all lines by that many spaces
|
- `indent_start` (default 0) -- prefix all lines by that many spaces
|
||||||
- `quote-keys` (default `false`) -- pass `true` to quote all keys in literal
|
- `quote_keys` (default `false`) -- pass `true` to quote all keys in literal
|
||||||
objects
|
objects
|
||||||
- `space-colon` (default `true`) -- insert a space after the colon signs
|
- `space_colon` (default `true`) -- insert a space after the colon signs
|
||||||
- `ascii-only` (default `false`) -- escape Unicode characters in strings and
|
- `ascii_only` (default `false`) -- escape Unicode characters in strings and
|
||||||
regexps (affects directives with non-ascii characters becoming invalid)
|
regexps (affects directives with non-ascii characters becoming invalid)
|
||||||
- `inline-script` (default `false`) -- escape the slash in occurrences of
|
- `inline_script` (default `false`) -- escape the slash in occurrences of
|
||||||
`</script` in strings
|
`</script` in strings
|
||||||
- `width` (default 80) -- only takes effect when beautification is on, this
|
- `width` (default 80) -- only takes effect when beautification is on, this
|
||||||
specifies an (orientative) line width that the beautifier will try to
|
specifies an (orientative) line width that the beautifier will try to
|
||||||
obey. It refers to the width of the line text (excluding indentation).
|
obey. It refers to the width of the line text (excluding indentation).
|
||||||
It doesn't work very well currently, but it does make the code generated
|
It doesn't work very well currently, but it does make the code generated
|
||||||
by UglifyJS more readable.
|
by UglifyJS more readable.
|
||||||
- `max-line-len` (default 32000) -- maximum line length (for uglified code)
|
- `max_line_len` (default 32000) -- maximum line length (for uglified code)
|
||||||
- `bracketize` (default `false`) -- always insert brackets in `if`, `for`,
|
- `bracketize` (default `false`) -- always insert brackets in `if`, `for`,
|
||||||
`do`, `while` or `with` statements, even if their body is a single
|
`do`, `while` or `with` statements, even if their body is a single
|
||||||
statement.
|
statement.
|
||||||
@@ -597,6 +597,7 @@ Example:
|
|||||||
```javascript
|
```javascript
|
||||||
var result = UglifyJS.minify("var b = function() {};");
|
var result = UglifyJS.minify("var b = function() {};");
|
||||||
console.log(result.code); // minified output
|
console.log(result.code); // minified output
|
||||||
|
console.log(result.error); // runtime error
|
||||||
```
|
```
|
||||||
|
|
||||||
You can also compress multiple files:
|
You can also compress multiple files:
|
||||||
|
|||||||
65
bin/uglifyjs
65
bin/uglifyjs
@@ -15,6 +15,7 @@ var path = require("path");
|
|||||||
var program = require("commander");
|
var program = require("commander");
|
||||||
var UglifyJS = require("../tools/node");
|
var UglifyJS = require("../tools/node");
|
||||||
|
|
||||||
|
var skip_keys = [ "cname", "enclosed", "parent_scope", "scope", "thedef", "uses_eval", "uses_with" ];
|
||||||
var files = {};
|
var files = {};
|
||||||
var options = {
|
var options = {
|
||||||
compress: false,
|
compress: false,
|
||||||
@@ -89,7 +90,7 @@ if (program.mangleProps) {
|
|||||||
if (typeof program.mangleProps != "object") program.mangleProps = {};
|
if (typeof program.mangleProps != "object") program.mangleProps = {};
|
||||||
if (!Array.isArray(program.mangleProps.reserved)) program.mangleProps.reserved = [];
|
if (!Array.isArray(program.mangleProps.reserved)) program.mangleProps.reserved = [];
|
||||||
require("../tools/domprops").forEach(function(name) {
|
require("../tools/domprops").forEach(function(name) {
|
||||||
UglifyJS.push_uniq(program.mangleProps.reserved, name);
|
UglifyJS._push_uniq(program.mangleProps.reserved, name);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (typeof options.mangle != "object") options.mangle = {};
|
if (typeof options.mangle != "object") options.mangle = {};
|
||||||
@@ -107,6 +108,12 @@ if (program.nameCache) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (program.output == "ast") {
|
||||||
|
options.output = {
|
||||||
|
ast: true,
|
||||||
|
code: false
|
||||||
|
};
|
||||||
|
}
|
||||||
if (program.parse) {
|
if (program.parse) {
|
||||||
if (program.parse.acorn || program.parse.spidermonkey) {
|
if (program.parse.acorn || program.parse.spidermonkey) {
|
||||||
if (program.sourceMap) fatal("ERROR: inline source map only works with built-in parser");
|
if (program.sourceMap) fatal("ERROR: inline source map only works with built-in parser");
|
||||||
@@ -185,9 +192,13 @@ function run() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var result = UglifyJS.minify(files, options);
|
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
if (ex instanceof UglifyJS.JS_Parse_Error) {
|
fatal(ex.stack);
|
||||||
|
}
|
||||||
|
var result = UglifyJS.minify(files, options);
|
||||||
|
if (result.error) {
|
||||||
|
var ex = result.error;
|
||||||
|
if (ex.name == "SyntaxError") {
|
||||||
console.error("Parse error at " + ex.filename + ":" + ex.line + "," + ex.col);
|
console.error("Parse error at " + ex.filename + ":" + ex.line + "," + ex.col);
|
||||||
var col = ex.col;
|
var col = ex.col;
|
||||||
var lines = files[ex.filename].split(/\r?\n/);
|
var lines = files[ex.filename].split(/\r?\n/);
|
||||||
@@ -209,10 +220,32 @@ function run() {
|
|||||||
console.error("Supported options:");
|
console.error("Supported options:");
|
||||||
console.error(ex.defs);
|
console.error(ex.defs);
|
||||||
}
|
}
|
||||||
fatal("ERROR: " + ex.message);
|
fatal(ex.stack);
|
||||||
|
} else if (program.output == "ast") {
|
||||||
|
console.log(JSON.stringify(result.ast, function(key, value) {
|
||||||
|
if (skip_key(key)) return;
|
||||||
|
if (value instanceof UglifyJS.AST_Token) return;
|
||||||
|
if (value instanceof UglifyJS.Dictionary) return;
|
||||||
|
if (value instanceof UglifyJS.AST_Node) {
|
||||||
|
var result = {
|
||||||
|
_class: "AST_" + value.TYPE
|
||||||
|
};
|
||||||
|
value.CTOR.PROPS.forEach(function(prop) {
|
||||||
|
result[prop] = value[prop];
|
||||||
|
});
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
if (program.output == "spidermonkey") {
|
return value;
|
||||||
console.log(JSON.stringify(UglifyJS.parse(result.code).to_mozilla_ast(), null, 2));
|
}, 2));
|
||||||
|
} else if (program.output == "spidermonkey") {
|
||||||
|
console.log(JSON.stringify(UglifyJS.minify(result.code, {
|
||||||
|
compress: false,
|
||||||
|
mangle: false,
|
||||||
|
output: {
|
||||||
|
ast: true,
|
||||||
|
code: false
|
||||||
|
}
|
||||||
|
}).ast.to_mozilla_ast(), null, 2));
|
||||||
} else if (program.output) {
|
} else if (program.output) {
|
||||||
fs.writeFileSync(program.output, result.code);
|
fs.writeFileSync(program.output, result.code);
|
||||||
if (result.map) {
|
if (result.map) {
|
||||||
@@ -230,7 +263,7 @@ function run() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function fatal(message) {
|
function fatal(message) {
|
||||||
console.error(message);
|
console.error(message.replace(/^\S*?Error:/, "ERROR:"));
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -270,7 +303,7 @@ function read_file(path, default_value) {
|
|||||||
return fs.readFileSync(path, "utf8");
|
return fs.readFileSync(path, "utf8");
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
if (ex.code == "ENOENT" && default_value != null) return default_value;
|
if (ex.code == "ENOENT" && default_value != null) return default_value;
|
||||||
fatal("ERROR: " + ex.message);
|
fatal(ex.stack);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -278,9 +311,17 @@ function parse_js(flag, constants) {
|
|||||||
return function(value, options) {
|
return function(value, options) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
try {
|
try {
|
||||||
UglifyJS.parse(value, {
|
UglifyJS.minify(value, {
|
||||||
|
parse: {
|
||||||
expression: true
|
expression: true
|
||||||
}).walk(new UglifyJS.TreeWalker(function(node) {
|
},
|
||||||
|
compress: false,
|
||||||
|
mangle: false,
|
||||||
|
output: {
|
||||||
|
ast: true,
|
||||||
|
code: false
|
||||||
|
}
|
||||||
|
}).ast.walk(new UglifyJS.TreeWalker(function(node) {
|
||||||
if (node instanceof UglifyJS.AST_Assign) {
|
if (node instanceof UglifyJS.AST_Assign) {
|
||||||
var name = node.left.print_to_string();
|
var name = node.left.print_to_string();
|
||||||
var value = node.right;
|
var value = node.right;
|
||||||
@@ -337,3 +378,7 @@ function to_cache(key) {
|
|||||||
}
|
}
|
||||||
return cache[key];
|
return cache[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function skip_key(key) {
|
||||||
|
return skip_keys.indexOf(key) >= 0;
|
||||||
|
}
|
||||||
|
|||||||
@@ -619,7 +619,7 @@ var AST_UnaryPostfix = DEFNODE("UnaryPostfix", null, {
|
|||||||
$documentation: "Unary postfix expression, i.e. `i++`"
|
$documentation: "Unary postfix expression, i.e. `i++`"
|
||||||
}, AST_Unary);
|
}, AST_Unary);
|
||||||
|
|
||||||
var AST_Binary = DEFNODE("Binary", "left operator right", {
|
var AST_Binary = DEFNODE("Binary", "operator left right", {
|
||||||
$documentation: "Binary expression, i.e. `a + b`",
|
$documentation: "Binary expression, i.e. `a + b`",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
left: "[AST_Node] left-hand side expression",
|
left: "[AST_Node] left-hand side expression",
|
||||||
|
|||||||
@@ -108,6 +108,11 @@ function minify(files, options) {
|
|||||||
toplevel = mangle_properties(toplevel, options.mangle.properties);
|
toplevel = mangle_properties(toplevel, options.mangle.properties);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
var result = {};
|
||||||
|
if (options.output.ast) {
|
||||||
|
result.ast = toplevel;
|
||||||
|
}
|
||||||
|
if (!HOP(options.output, "code") || options.output.code) {
|
||||||
if (options.sourceMap) {
|
if (options.sourceMap) {
|
||||||
if (typeof options.sourceMap.content == "string") {
|
if (typeof options.sourceMap.content == "string") {
|
||||||
options.sourceMap.content = JSON.parse(options.sourceMap.content);
|
options.sourceMap.content = JSON.parse(options.sourceMap.content);
|
||||||
@@ -123,11 +128,11 @@ function minify(files, options) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
delete options.output.ast;
|
||||||
|
delete options.output.code;
|
||||||
var stream = OutputStream(options.output);
|
var stream = OutputStream(options.output);
|
||||||
toplevel.print(stream);
|
toplevel.print(stream);
|
||||||
var result = {
|
result.code = stream.get();
|
||||||
code: stream.get()
|
|
||||||
};
|
|
||||||
if (options.sourceMap) {
|
if (options.sourceMap) {
|
||||||
result.map = options.output.source_map.toString();
|
result.map = options.output.source_map.toString();
|
||||||
if (options.sourceMap.url == "inline") {
|
if (options.sourceMap.url == "inline") {
|
||||||
@@ -136,10 +141,13 @@ function minify(files, options) {
|
|||||||
result.code += "\n//# sourceMappingURL=" + options.sourceMap.url;
|
result.code += "\n//# sourceMappingURL=" + options.sourceMap.url;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (warnings.length) {
|
if (warnings.length) {
|
||||||
result.warnings = warnings;
|
result.warnings = warnings;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
} catch (ex) {
|
||||||
|
return { error: ex };
|
||||||
} finally {
|
} finally {
|
||||||
AST_Node.warn_function = warn_function;
|
AST_Node.warn_function = warn_function;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
"homepage": "http://lisperator.net/uglifyjs",
|
"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.0.0",
|
"version": "3.0.2",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.8.0"
|
"node": ">=0.8.0"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -2440,8 +2440,8 @@ issue_1865: {
|
|||||||
unsafe: true,
|
unsafe: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f(a) {
|
function f(some) {
|
||||||
a.b = false;
|
some.thing = false;
|
||||||
}
|
}
|
||||||
console.log(function() {
|
console.log(function() {
|
||||||
var some = { thing: true };
|
var some = { thing: true };
|
||||||
@@ -2450,8 +2450,8 @@ issue_1865: {
|
|||||||
}());
|
}());
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function f(a) {
|
function f(some) {
|
||||||
a.b = false;
|
some.thing = false;
|
||||||
}
|
}
|
||||||
console.log(function() {
|
console.log(function() {
|
||||||
var some = { thing: true };
|
var some = { thing: true };
|
||||||
|
|||||||
13
test/exports.js
Normal file
13
test/exports.js
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
exports["Compressor"] = Compressor;
|
||||||
|
exports["JS_Parse_Error"] = JS_Parse_Error;
|
||||||
|
exports["OutputStream"] = OutputStream;
|
||||||
|
exports["SourceMap"] = SourceMap;
|
||||||
|
exports["TreeWalker"] = TreeWalker;
|
||||||
|
exports["base54"] = base54;
|
||||||
|
exports["defaults"] = defaults;
|
||||||
|
exports["mangle_properties"] = mangle_properties;
|
||||||
|
exports["minify"] = minify;
|
||||||
|
exports["parse"] = parse;
|
||||||
|
exports["string_template"] = string_template;
|
||||||
|
exports["tokenizer"] = tokenizer;
|
||||||
|
exports["is_identifier"] = is_identifier;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
var UglifyJS = require('../../');
|
var UglifyJS = require("../node");
|
||||||
var assert = require("assert");
|
var assert = require("assert");
|
||||||
|
|
||||||
describe("Accessor tokens", function() {
|
describe("Accessor tokens", function() {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
var UglifyJS = require('../../');
|
var UglifyJS = require("../node");
|
||||||
var assert = require("assert");
|
var assert = require("assert");
|
||||||
|
|
||||||
describe("arguments", function() {
|
describe("arguments", function() {
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ describe("bin/uglifyjs", function () {
|
|||||||
eval(stdout);
|
eval(stdout);
|
||||||
|
|
||||||
assert.strictEqual(typeof WrappedUglifyJS, 'object');
|
assert.strictEqual(typeof WrappedUglifyJS, 'object');
|
||||||
assert.strictEqual(true, WrappedUglifyJS.parse('foo;') instanceof WrappedUglifyJS.AST_Node);
|
assert.strictEqual(WrappedUglifyJS.minify("foo([true,,2+3]);").code, "foo([!0,,5]);");
|
||||||
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
@@ -185,7 +185,7 @@ describe("bin/uglifyjs", function () {
|
|||||||
|
|
||||||
exec(command, function (err, stdout, stderr) {
|
exec(command, function (err, stdout, stderr) {
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
assert.strictEqual(stderr, "ERROR: inline source map only works with singular input\n");
|
assert.strictEqual(stderr.split(/\n/)[0], "ERROR: inline source map only works with singular input");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -509,4 +509,15 @@ describe("bin/uglifyjs", function () {
|
|||||||
return JSON.stringify(map).replace(/"/g, '\\"');
|
return JSON.stringify(map).replace(/"/g, '\\"');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
it("Should dump AST as JSON", function(done) {
|
||||||
|
var command = uglifyjscmd + " test/input/global_defs/simple.js -mco ast";
|
||||||
|
exec(command, function (err, stdout) {
|
||||||
|
if (err) throw err;
|
||||||
|
|
||||||
|
var ast = JSON.parse(stdout);
|
||||||
|
assert.strictEqual(ast._class, "AST_Toplevel");
|
||||||
|
assert.ok(Array.isArray(ast.body));
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
var UglifyJS = require('../../');
|
var UglifyJS = require("../node");
|
||||||
var assert = require("assert");
|
var assert = require("assert");
|
||||||
|
|
||||||
describe("comment filters", function() {
|
describe("comment filters", function() {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
var assert = require("assert");
|
var assert = require("assert");
|
||||||
var uglify = require("../../");
|
var uglify = require("../node");
|
||||||
|
|
||||||
describe("Comment", function() {
|
describe("Comment", function() {
|
||||||
it("Should recognize eol of single line comments", function() {
|
it("Should recognize eol of single line comments", function() {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
var assert = require("assert");
|
var assert = require("assert");
|
||||||
var uglify = require("../../");
|
var uglify = require("../node");
|
||||||
|
|
||||||
describe("Directives", function() {
|
describe("Directives", function() {
|
||||||
it ("Should allow tokenizer to store directives state", function() {
|
it ("Should allow tokenizer to store directives state", function() {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
var UglifyJS = require('../../');
|
var UglifyJS = require("../node");
|
||||||
var assert = require("assert");
|
var assert = require("assert");
|
||||||
|
|
||||||
describe("Getters and setters", function() {
|
describe("Getters and setters", function() {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
var Uglify = require('../../');
|
var Uglify = require("../node");
|
||||||
var assert = require("assert");
|
var assert = require("assert");
|
||||||
|
|
||||||
describe("line-endings", function() {
|
describe("line-endings", function() {
|
||||||
|
|||||||
@@ -114,8 +114,7 @@ describe("minify", function() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
it("Should fail with multiple input and inline source map", function() {
|
it("Should fail with multiple input and inline source map", function() {
|
||||||
assert.throws(function() {
|
var result = Uglify.minify([
|
||||||
Uglify.minify([
|
|
||||||
read("./test/input/issue-520/input.js"),
|
read("./test/input/issue-520/input.js"),
|
||||||
read("./test/input/issue-520/output.js")
|
read("./test/input/issue-520/output.js")
|
||||||
], {
|
], {
|
||||||
@@ -124,7 +123,9 @@ describe("minify", function() {
|
|||||||
url: "inline"
|
url: "inline"
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
var err = result.error;
|
||||||
|
assert.ok(err instanceof Error);
|
||||||
|
assert.strictEqual(err.stack.split(/\n/)[0], "Error: inline source map only works with singular input");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -170,26 +171,14 @@ describe("minify", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("JS_Parse_Error", function() {
|
describe("JS_Parse_Error", function() {
|
||||||
it("should throw syntax error", function() {
|
it("should return syntax error", function() {
|
||||||
assert.throws(function() {
|
var result = Uglify.minify("function f(a{}");
|
||||||
Uglify.minify("function f(a{}");
|
var err = result.error;
|
||||||
}, function(err) {
|
|
||||||
assert.ok(err instanceof Error);
|
assert.ok(err instanceof Error);
|
||||||
assert.strictEqual(err.stack.split(/\n/)[0], "SyntaxError: Unexpected token punc «{», expected punc «,»");
|
assert.strictEqual(err.stack.split(/\n/)[0], "SyntaxError: Unexpected token punc «{», expected punc «,»");
|
||||||
assert.strictEqual(err.filename, "0");
|
assert.strictEqual(err.filename, "0");
|
||||||
assert.strictEqual(err.line, 1);
|
assert.strictEqual(err.line, 1);
|
||||||
assert.strictEqual(err.col, 12);
|
assert.strictEqual(err.col, 12);
|
||||||
return true;
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
describe("Compressor", function() {
|
|
||||||
it("should be backward compatible with ast.transform(compressor)", function() {
|
|
||||||
var ast = Uglify.parse("function f(a){for(var i=0;i<a;i++)console.log(i)}");
|
|
||||||
ast.figure_out_scope();
|
|
||||||
ast = ast.transform(Uglify.Compressor());
|
|
||||||
assert.strictEqual(ast.print_to_string(), "function f(a){for(var i=0;i<a;i++)console.log(i)}");
|
|
||||||
});
|
|
||||||
})
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
var assert = require("assert");
|
var assert = require("assert");
|
||||||
var uglify = require("../../");
|
var uglify = require("../node");
|
||||||
|
|
||||||
describe("Number literals", function () {
|
describe("Number literals", function () {
|
||||||
it("Should not allow legacy octal literals in strict mode", function() {
|
it("Should not allow legacy octal literals in strict mode", function() {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
var UglifyJS = require("../../");
|
var UglifyJS = require("../node");
|
||||||
var assert = require("assert");
|
var assert = require("assert");
|
||||||
|
|
||||||
describe("operator", function() {
|
describe("operator", function() {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
var assert = require("assert");
|
var assert = require("assert");
|
||||||
var exec = require("child_process").exec;
|
var exec = require("child_process").exec;
|
||||||
var uglify = require("../../");
|
var uglify = require("../node");
|
||||||
|
|
||||||
describe("spidermonkey export/import sanity test", function() {
|
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) {
|
||||||
@@ -15,18 +15,7 @@ describe("spidermonkey export/import sanity test", function() {
|
|||||||
|
|
||||||
eval(stdout);
|
eval(stdout);
|
||||||
assert.strictEqual(typeof SpiderUglify, "object");
|
assert.strictEqual(typeof SpiderUglify, "object");
|
||||||
|
assert.strictEqual(SpiderUglify.minify("foo([true,,2+3]);").code, "foo([!0,,5]);");
|
||||||
var ast = SpiderUglify.parse("foo([true,,2+3]);");
|
|
||||||
assert.strictEqual(true, ast instanceof SpiderUglify.AST_Node);
|
|
||||||
|
|
||||||
ast.figure_out_scope();
|
|
||||||
ast = SpiderUglify.Compressor({}).compress(ast);
|
|
||||||
assert.strictEqual(true, ast instanceof SpiderUglify.AST_Node);
|
|
||||||
|
|
||||||
var stream = SpiderUglify.OutputStream({});
|
|
||||||
ast.print(stream);
|
|
||||||
var code = stream.toString();
|
|
||||||
assert.strictEqual(code, "foo([!0,,5]);");
|
|
||||||
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
var UglifyJS = require('../../');
|
var UglifyJS = require("../node");
|
||||||
var assert = require("assert");
|
var assert = require("assert");
|
||||||
|
|
||||||
describe("String literals", function() {
|
describe("String literals", function() {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
var assert = require("assert");
|
var assert = require("assert");
|
||||||
var uglify = require("../../");
|
var uglify = require("../node");
|
||||||
|
|
||||||
describe("With", function() {
|
describe("With", function() {
|
||||||
it("Should throw syntaxError when using with statement in strict mode", function() {
|
it("Should throw syntaxError when using with statement in strict mode", function() {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// Testing UglifyJS <-> SpiderMonkey AST conversion
|
// Testing UglifyJS <-> SpiderMonkey AST conversion
|
||||||
// through generative testing.
|
// through generative testing.
|
||||||
|
|
||||||
var UglifyJS = require(".."),
|
var UglifyJS = require("./node"),
|
||||||
escodegen = require("escodegen"),
|
escodegen = require("escodegen"),
|
||||||
esfuzz = require("esfuzz"),
|
esfuzz = require("esfuzz"),
|
||||||
estraverse = require("estraverse"),
|
estraverse = require("estraverse"),
|
||||||
|
|||||||
6
test/node.js
Normal file
6
test/node.js
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
var fs = require("fs");
|
||||||
|
|
||||||
|
new Function("MOZ_SourceMap", "exports", require("../tools/node").FILES.map(function(file) {
|
||||||
|
if (/exports\.js$/.test(file)) file = require.resolve("./exports");
|
||||||
|
return fs.readFileSync(file, "utf8");
|
||||||
|
}).join("\n\n"))(require("source-map"), exports);
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
#! /usr/bin/env node
|
#! /usr/bin/env node
|
||||||
|
|
||||||
var U = require("../tools/node");
|
var U = require("./node");
|
||||||
var path = require("path");
|
var path = require("path");
|
||||||
var fs = require("fs");
|
var fs = require("fs");
|
||||||
var assert = require("assert");
|
var assert = require("assert");
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
var UglifyJS = require("..");
|
var UglifyJS = require("./node");
|
||||||
var ok = require("assert");
|
var ok = require("assert");
|
||||||
|
|
||||||
module.exports = function () {
|
module.exports = function () {
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
stream._handle.setBlocking(true);
|
stream._handle.setBlocking(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
var UglifyJS = require("..");
|
var UglifyJS = require("./node");
|
||||||
var randomBytes = require("crypto").randomBytes;
|
var randomBytes = require("crypto").randomBytes;
|
||||||
var sandbox = require("./sandbox");
|
var sandbox = require("./sandbox");
|
||||||
|
|
||||||
@@ -856,7 +856,6 @@ function createVarName(maybe, dontStore) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function try_beautify(code, result) {
|
function try_beautify(code, result) {
|
||||||
try {
|
|
||||||
var beautified = UglifyJS.minify(code, {
|
var beautified = UglifyJS.minify(code, {
|
||||||
compress: false,
|
compress: false,
|
||||||
mangle: false,
|
mangle: false,
|
||||||
@@ -864,15 +863,14 @@ function try_beautify(code, result) {
|
|||||||
beautify: true,
|
beautify: true,
|
||||||
bracketize: true,
|
bracketize: true,
|
||||||
},
|
},
|
||||||
}).code;
|
});
|
||||||
if (sandbox.same_stdout(sandbox.run_code(beautified), result)) {
|
if (beautified.error) {
|
||||||
console.log("// (beautified)");
|
|
||||||
console.log(beautified);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.log("// !!! beautify failed !!!");
|
console.log("// !!! beautify failed !!!");
|
||||||
console.log(e.stack);
|
console.log(beautified.error.stack);
|
||||||
|
} else if (sandbox.same_stdout(sandbox.run_code(beautified.code), result)) {
|
||||||
|
console.log("// (beautified)");
|
||||||
|
console.log(beautified.code);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
console.log("//");
|
console.log("//");
|
||||||
console.log(code);
|
console.log(code);
|
||||||
@@ -908,12 +906,13 @@ function log_suspects(minify_options, component) {
|
|||||||
var o = JSON.parse(JSON.stringify(options));
|
var o = JSON.parse(JSON.stringify(options));
|
||||||
o[name] = false;
|
o[name] = false;
|
||||||
m[component] = o;
|
m[component] = o;
|
||||||
try {
|
var result = UglifyJS.minify(original_code, m);
|
||||||
var r = sandbox.run_code(UglifyJS.minify(original_code, m).code);
|
if (result.error) {
|
||||||
return sandbox.same_stdout(original_result, r);
|
|
||||||
} catch (e) {
|
|
||||||
console.log("Error testing options." + component + "." + name);
|
console.log("Error testing options." + component + "." + name);
|
||||||
console.log(e);
|
console.log(result.error);
|
||||||
|
} else {
|
||||||
|
var r = sandbox.run_code(result.code);
|
||||||
|
return sandbox.same_stdout(original_result, r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -981,19 +980,17 @@ for (var round = 1; round <= num_iterations; round++) {
|
|||||||
original_code = createTopLevelCode();
|
original_code = createTopLevelCode();
|
||||||
original_result = sandbox.run_code(original_code);
|
original_result = sandbox.run_code(original_code);
|
||||||
(typeof original_result != "string" ? fallback_options : minify_options).forEach(function(options) {
|
(typeof original_result != "string" ? fallback_options : minify_options).forEach(function(options) {
|
||||||
try {
|
uglify_code = UglifyJS.minify(original_code, JSON.parse(options));
|
||||||
uglify_code = UglifyJS.minify(original_code, JSON.parse(options)).code;
|
if (!uglify_code.error) {
|
||||||
} catch (e) {
|
uglify_code = uglify_code.code;
|
||||||
uglify_code = e;
|
|
||||||
}
|
|
||||||
|
|
||||||
ok = typeof uglify_code == "string";
|
|
||||||
if (ok) {
|
|
||||||
uglify_result = sandbox.run_code(uglify_code);
|
uglify_result = sandbox.run_code(uglify_code);
|
||||||
ok = sandbox.same_stdout(original_result, uglify_result);
|
ok = sandbox.same_stdout(original_result, uglify_result);
|
||||||
} else if (typeof original_result != "string") {
|
} else {
|
||||||
|
uglify_code = uglify_code.error;
|
||||||
|
if (typeof original_result != "string") {
|
||||||
ok = uglify_code.name == original_result.name;
|
ok = uglify_code.name == original_result.name;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (verbose || (verbose_interval && !(round % INTERVAL_COUNT)) || !ok) log(options);
|
if (verbose || (verbose_interval && !(round % INTERVAL_COUNT)) || !ok) log(options);
|
||||||
else if (verbose_error && typeof original_result != "string") {
|
else if (verbose_error && typeof original_result != "string") {
|
||||||
console.log("//=============================================================");
|
console.log("//=============================================================");
|
||||||
|
|||||||
@@ -1,15 +1,4 @@
|
|||||||
exports["Compressor"] = Compressor;
|
|
||||||
exports["Dictionary"] = Dictionary;
|
exports["Dictionary"] = Dictionary;
|
||||||
exports["JS_Parse_Error"] = JS_Parse_Error;
|
|
||||||
exports["OutputStream"] = OutputStream;
|
|
||||||
exports["SourceMap"] = SourceMap;
|
|
||||||
exports["TreeWalker"] = TreeWalker;
|
exports["TreeWalker"] = TreeWalker;
|
||||||
exports["base54"] = base54;
|
|
||||||
exports["defaults"] = defaults;
|
|
||||||
exports["mangle_properties"] = mangle_properties;
|
|
||||||
exports["minify"] = minify;
|
exports["minify"] = minify;
|
||||||
exports["parse"] = parse;
|
exports["_push_uniq"] = push_uniq;
|
||||||
exports["push_uniq"] = push_uniq;
|
|
||||||
exports["string_template"] = string_template;
|
|
||||||
exports["tokenizer"] = tokenizer;
|
|
||||||
exports["is_identifier"] = is_identifier;
|
|
||||||
|
|||||||
@@ -18,15 +18,19 @@ var FILES = UglifyJS.FILES = [
|
|||||||
return require.resolve(file);
|
return require.resolve(file);
|
||||||
});
|
});
|
||||||
|
|
||||||
new Function("MOZ_SourceMap", "exports", FILES.map(function(file){
|
new Function("MOZ_SourceMap", "exports", function() {
|
||||||
|
var code = FILES.map(function(file) {
|
||||||
return fs.readFileSync(file, "utf8");
|
return fs.readFileSync(file, "utf8");
|
||||||
}).join("\n\n"))(
|
});
|
||||||
|
code.push("exports.describe_ast = " + describe_ast.toString());
|
||||||
|
return code.join("\n\n");
|
||||||
|
}())(
|
||||||
require("source-map"),
|
require("source-map"),
|
||||||
UglifyJS
|
UglifyJS
|
||||||
);
|
);
|
||||||
|
|
||||||
UglifyJS.describe_ast = function() {
|
function describe_ast() {
|
||||||
var out = UglifyJS.OutputStream({ beautify: true });
|
var out = OutputStream({ beautify: true });
|
||||||
function doitem(ctor) {
|
function doitem(ctor) {
|
||||||
out.print("AST_" + ctor.TYPE);
|
out.print("AST_" + ctor.TYPE);
|
||||||
var props = ctor.SELF_PROPS.filter(function(prop){
|
var props = ctor.SELF_PROPS.filter(function(prop){
|
||||||
@@ -56,6 +60,6 @@ UglifyJS.describe_ast = function() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
doitem(UglifyJS.AST_Node);
|
doitem(AST_Node);
|
||||||
return out + "";
|
return out + "";
|
||||||
};
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user