Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
daaefc17b9 | ||
|
|
1d407e761e | ||
|
|
2b44f4ae30 | ||
|
|
e51c3541da | ||
|
|
3bf194684b | ||
|
|
aae7d49d0c | ||
|
|
0459af2ecc | ||
|
|
04f2344efc | ||
|
|
bad9d5cf88 | ||
|
|
a0f5f862df | ||
|
|
41996be86f |
10
.github/ISSUE_TEMPLATE.md
vendored
10
.github/ISSUE_TEMPLATE.md
vendored
@@ -6,15 +6,15 @@
|
|||||||
|
|
||||||
<!-- Note: for ES6 see: https://github.com/mishoo/UglifyJS2/tree/harmony#harmony -->
|
<!-- Note: for ES6 see: https://github.com/mishoo/UglifyJS2/tree/harmony#harmony -->
|
||||||
|
|
||||||
**`uglify-js` version (`uglifyjs -V`)**
|
**Uglify version (`uglifyjs -V`)**
|
||||||
|
|
||||||
**JavaScript input - ideally as small as possible.**
|
**JavaScript input** <!-- ideally as small as possible -->
|
||||||
|
|
||||||
**The `uglifyjs` CLI command executed or `minify()` options used.**
|
**The `uglifyjs` CLI command executed or `minify()` options used.**
|
||||||
|
|
||||||
**JavaScript output produced and/or the error or warning.**
|
**JavaScript output or error produced.**
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Note: the release version of uglify-js only supports ES5. Those wishing
|
Note: `uglify-js` only supports ES5.
|
||||||
to minify ES6 should use the experimental harmony branch.
|
Those wishing to minify ES6 should use `uglify-es`.
|
||||||
-->
|
-->
|
||||||
|
|||||||
117
README.md
117
README.md
@@ -2,14 +2,14 @@ UglifyJS 3
|
|||||||
==========
|
==========
|
||||||
[](https://travis-ci.org/mishoo/UglifyJS2)
|
[](https://travis-ci.org/mishoo/UglifyJS2)
|
||||||
|
|
||||||
UglifyJS is a JavaScript parser, minifier, compressor or beautifier toolkit.
|
UglifyJS is a JavaScript parser, minifier, compressor and beautifier toolkit.
|
||||||
|
|
||||||
#### Note:
|
#### Note:
|
||||||
- **`uglify-js@3.x` has a new API and CLI and is not backwards compatible with [`uglify-js@2.x`](https://github.com/mishoo/UglifyJS2/tree/v2.x)**.
|
- **`uglify-js@3.x` has a new API and CLI and is not backwards compatible with [`uglify-js@2.x`](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)**.
|
||||||
- Release versions of `uglify-js` only support ECMAScript 5 (ES5). If you wish to minify
|
- `uglify-js` only supports ECMAScript 5 (ES5).
|
||||||
ES2015+ (ES6+) code then please use the [harmony](#harmony) development branch.
|
- Those wishing to minify
|
||||||
- Node 7 has a known performance regression and runs `uglify-js` twice as slow.
|
ES2015+ (ES6+) should use the `npm` package [**uglify-es**](https://github.com/mishoo/UglifyJS2/tree/harmony).
|
||||||
|
|
||||||
Install
|
Install
|
||||||
-------
|
-------
|
||||||
@@ -25,12 +25,6 @@ From NPM for programmatic use:
|
|||||||
|
|
||||||
npm install uglify-js
|
npm install uglify-js
|
||||||
|
|
||||||
From Git:
|
|
||||||
|
|
||||||
git clone git://github.com/mishoo/UglifyJS2.git
|
|
||||||
cd UglifyJS2
|
|
||||||
npm link .
|
|
||||||
|
|
||||||
Usage
|
Usage
|
||||||
-----
|
-----
|
||||||
|
|
||||||
@@ -155,16 +149,21 @@ debugging your compressed JavaScript. To get a source map, pass
|
|||||||
`--source-map --output output.js` (source map will be written out to
|
`--source-map --output output.js` (source map will be written out to
|
||||||
`output.js.map`).
|
`output.js.map`).
|
||||||
|
|
||||||
Additionally you might need `--source-map root=<URL>` to pass the URL where
|
Additional options:
|
||||||
the original files can be found. Use `--source-map url=<URL>` to specify
|
|
||||||
the URL where the source map can be found.
|
- `--source-map filename=<NAME>` to specify the name of the source map.
|
||||||
|
|
||||||
|
- `--source-map root=<URL>` to pass the URL where the original files can be found.
|
||||||
|
Otherwise UglifyJS assumes HTTP `X-SourceMap` is being used and will omit the
|
||||||
|
`//# sourceMappingURL=` directive.
|
||||||
|
|
||||||
|
- `--source-map url=<URL>` to specify the URL where the source map can be found.
|
||||||
|
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
uglifyjs /home/doe/work/foo/src/js/file1.js \
|
uglifyjs js/file1.js js/file2.js \
|
||||||
/home/doe/work/foo/src/js/file2.js \
|
|
||||||
-o foo.min.js -c -m \
|
-o foo.min.js -c -m \
|
||||||
--source-map base="/home/doe/work/foo/src",root="http://foo.com/src"
|
--source-map root="http://foo.com/src",url=foo.min.js.map
|
||||||
|
|
||||||
The above will compress and mangle `file1.js` and `file2.js`, will drop the
|
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
|
output in `foo.min.js` and the source map in `foo.min.js.map`. The source
|
||||||
@@ -183,11 +182,9 @@ CoffeeScript → compiled JS, UglifyJS can generate a map from CoffeeScript →
|
|||||||
compressed JS by mapping every token in the compiled JS to its original
|
compressed JS by mapping every token in the compiled JS to its original
|
||||||
location.
|
location.
|
||||||
|
|
||||||
To use this feature you need to pass `--in-source-map
|
To use this feature pass `--source-map content="/path/to/input/source.map"`
|
||||||
/path/to/input/source.map` or `--in-source-map inline` if the source map is
|
or `--source-map content=inline` if the source map is included inline with
|
||||||
included inline with the sources. Normally the input source map should also
|
the sources.
|
||||||
point to the file containing the generated JS, so if that's correct you can
|
|
||||||
omit input files from the command line.
|
|
||||||
|
|
||||||
## Mangler options
|
## Mangler options
|
||||||
|
|
||||||
@@ -470,7 +467,7 @@ You can also use conditional compilation via the programmatic API. With the diff
|
|||||||
property name is `global_defs` and is a compressor property:
|
property name is `global_defs` and is a compressor property:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
uglifyJS.minify([ "input.js"], {
|
uglifyJS.minify(fs.readFileSync("input.js", "utf8"), {
|
||||||
compress: {
|
compress: {
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
global_defs: {
|
global_defs: {
|
||||||
@@ -676,61 +673,47 @@ Other options:
|
|||||||
|
|
||||||
##### mangle
|
##### mangle
|
||||||
|
|
||||||
- `reserved` - pass an array of identifiers that should be excluded from mangling
|
- `reserved` - pass an array of identifiers that should be excluded from mangling
|
||||||
|
|
||||||
- `toplevel` — mangle names declared in the toplevel scope (disabled by
|
- `toplevel` — mangle names declared in the toplevel scope (disabled by
|
||||||
default).
|
default).
|
||||||
|
|
||||||
- `eval` — mangle names visible in scopes where eval or with are used
|
- `eval` — mangle names visible in scopes where eval or with are used
|
||||||
(disabled by default).
|
(disabled by default).
|
||||||
|
|
||||||
- `keep_fnames` -- default `false`. Pass `true` to not mangle
|
- `keep_fnames` -- default `false`. Pass `true` to not mangle
|
||||||
function names. Useful for code relying on `Function.prototype.name`.
|
function names. Useful for code relying on `Function.prototype.name`.
|
||||||
See also: the `keep_fnames` [compress option](#compressor-options).
|
See also: the `keep_fnames` [compress option](#compressor-options).
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
//tst.js
|
// test.js
|
||||||
var globalVar;
|
var globalVar;
|
||||||
function funcName(firstLongName, anotherLongName)
|
function funcName(firstLongName, anotherLongName)
|
||||||
{
|
{
|
||||||
var myVariable = firstLongName + anotherLongName;
|
var myVariable = firstLongName + anotherLongName;
|
||||||
}
|
}
|
||||||
|
```
|
||||||
|
```javascript
|
||||||
|
var code = fs.readFileSync("test.js", "utf8");
|
||||||
|
|
||||||
UglifyJS.minify("tst.js").code;
|
UglifyJS.minify(code).code;
|
||||||
// 'function funcName(a,n){}var globalVar;'
|
// 'function funcName(a,n){}var globalVar;'
|
||||||
|
|
||||||
UglifyJS.minify("tst.js", { mangle: { reserved: ['firstLongName'] } }).code;
|
UglifyJS.minify(code, { mangle: { reserved: ['firstLongName'] } }).code;
|
||||||
// 'function funcName(firstLongName,a){}var globalVar;'
|
// 'function funcName(firstLongName,a){}var globalVar;'
|
||||||
|
|
||||||
UglifyJS.minify("tst.js", { mangle: { toplevel: true } }).code;
|
UglifyJS.minify(code, { mangle: { toplevel: true } }).code;
|
||||||
// 'function n(n,a){}var a;'
|
// 'function n(n,a){}var a;'
|
||||||
```
|
```
|
||||||
|
|
||||||
##### mangle.properties options
|
##### mangle.properties options
|
||||||
|
|
||||||
- `regex` — Pass a RegExp to only mangle certain names
|
- `regex` — Pass a RegExp to only mangle certain names
|
||||||
- `keep_quoted` — Only mangle unquoted property names
|
- `keep_quoted` — Only mangle unquoted property names
|
||||||
- `debug` — Mangle names with the original name still present. Defaults to `false`.
|
- `debug` — Mangle names with the original name still present. Defaults to `false`.
|
||||||
Pass an empty string to enable, or a non-empty string to set the suffix.
|
Pass an empty string to enable, or a non-empty string to set the suffix.
|
||||||
|
|
||||||
[acorn]: https://github.com/ternjs/acorn
|
[acorn]: https://github.com/ternjs/acorn
|
||||||
[sm-spec]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k
|
[sm-spec]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k
|
||||||
|
|
||||||
#### Harmony
|
|
||||||
|
|
||||||
If you wish to use the experimental [harmony](https://github.com/mishoo/UglifyJS2/commits/harmony)
|
|
||||||
branch to minify ES2015+ (ES6+) code please use the following in your `package.json` file:
|
|
||||||
|
|
||||||
```
|
|
||||||
"uglify-js": "git+https://github.com/mishoo/UglifyJS2.git#harmony"
|
|
||||||
```
|
|
||||||
|
|
||||||
or to directly install the experimental harmony version of uglify:
|
|
||||||
|
|
||||||
```
|
|
||||||
npm install --save-dev uglify-js@github:mishoo/UglifyJS2#harmony
|
|
||||||
```
|
|
||||||
|
|
||||||
See [#448](https://github.com/mishoo/UglifyJS2/issues/448) for additional details.
|
|
||||||
|
|||||||
@@ -193,7 +193,7 @@ function run() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
fatal(ex.stack);
|
fatal(ex);
|
||||||
}
|
}
|
||||||
var result = UglifyJS.minify(files, options);
|
var result = UglifyJS.minify(files, options);
|
||||||
if (result.error) {
|
if (result.error) {
|
||||||
@@ -220,7 +220,7 @@ function run() {
|
|||||||
console.error("Supported options:");
|
console.error("Supported options:");
|
||||||
console.error(ex.defs);
|
console.error(ex.defs);
|
||||||
}
|
}
|
||||||
fatal(ex.stack);
|
fatal(ex);
|
||||||
} else if (program.output == "ast") {
|
} else if (program.output == "ast") {
|
||||||
console.log(JSON.stringify(result.ast, function(key, value) {
|
console.log(JSON.stringify(result.ast, function(key, value) {
|
||||||
if (skip_key(key)) return;
|
if (skip_key(key)) return;
|
||||||
@@ -263,7 +263,8 @@ function run() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function fatal(message) {
|
function fatal(message) {
|
||||||
console.error(message.replace(/^\S*?Error:/, "ERROR:"));
|
if (message instanceof Error) message = message.stack.replace(/^\S*?Error:/, "ERROR:")
|
||||||
|
console.error(message);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -303,7 +304,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(ex.stack);
|
fatal(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -525,6 +525,14 @@ merge(Compressor.prototype, {
|
|||||||
return lhs instanceof AST_SymbolRef && lhs.definition().orig[0] instanceof AST_SymbolLambda;
|
return lhs instanceof AST_SymbolRef && lhs.definition().orig[0] instanceof AST_SymbolLambda;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function is_reference_const(ref) {
|
||||||
|
if (!(ref instanceof AST_SymbolRef)) return false;
|
||||||
|
var orig = ref.definition().orig;
|
||||||
|
for (var i = orig.length; --i >= 0;) {
|
||||||
|
if (orig[i] instanceof AST_SymbolConst) return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function find_variable(compressor, name) {
|
function find_variable(compressor, name) {
|
||||||
var scope, i = 0;
|
var scope, i = 0;
|
||||||
while (scope = compressor.parent(i++)) {
|
while (scope = compressor.parent(i++)) {
|
||||||
@@ -790,7 +798,8 @@ merge(Compressor.prototype, {
|
|||||||
return make_node(AST_SymbolRef, expr.name, expr.name);
|
return make_node(AST_SymbolRef, expr.name, expr.name);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return expr[expr instanceof AST_Assign ? "left" : "expression"];
|
var lhs = expr[expr instanceof AST_Assign ? "left" : "expression"];
|
||||||
|
return !is_reference_const(lhs) && lhs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1973,6 +1982,7 @@ merge(Compressor.prototype, {
|
|||||||
&& node instanceof AST_Assign
|
&& node instanceof AST_Assign
|
||||||
&& node.operator == "="
|
&& node.operator == "="
|
||||||
&& node.left instanceof AST_SymbolRef
|
&& node.left instanceof AST_SymbolRef
|
||||||
|
&& !is_reference_const(node.left)
|
||||||
&& scope === self) {
|
&& scope === self) {
|
||||||
node.right.walk(tw);
|
node.right.walk(tw);
|
||||||
return true;
|
return true;
|
||||||
@@ -3178,7 +3188,7 @@ merge(Compressor.prototype, {
|
|||||||
&& (left.operator == "++" || left.operator == "--")) {
|
&& (left.operator == "++" || left.operator == "--")) {
|
||||||
left = left.expression;
|
left = left.expression;
|
||||||
} else left = null;
|
} else left = null;
|
||||||
if (!left || is_lhs_read_only(left)) {
|
if (!left || is_lhs_read_only(left) || is_reference_const(left)) {
|
||||||
expressions[++i] = cdr;
|
expressions[++i] = cdr;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.2",
|
"version": "3.0.4",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.8.0"
|
"node": ">=0.8.0"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -2186,3 +2186,49 @@ compound_assignment: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "4"
|
expect_stdout: "4"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reassign_const_1: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
const a = 1;
|
||||||
|
a = 2;
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
console.log(f());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
const a = 1;
|
||||||
|
a = 2;
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
console.log(f());
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
reassign_const_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
const a = 1;
|
||||||
|
++a;
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
console.log(f());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
const a = 1;
|
||||||
|
++a;
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
console.log(f());
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|||||||
@@ -1147,3 +1147,28 @@ var_catch_toplevel: {
|
|||||||
}();
|
}();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reassign_const: {
|
||||||
|
options = {
|
||||||
|
cascade: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
const a = 1;
|
||||||
|
a = 2;
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
console.log(f());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
const a = 1;
|
||||||
|
return a = 2, a;
|
||||||
|
}
|
||||||
|
console.log(f());
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|||||||
@@ -710,3 +710,27 @@ issue_27: {
|
|||||||
})(jQuery);
|
})(jQuery);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reassign_const: {
|
||||||
|
options = {
|
||||||
|
cascade: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
const a = 1;
|
||||||
|
a++;
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
console.log(f());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
const a = 1;
|
||||||
|
return a++, a;
|
||||||
|
}
|
||||||
|
console.log(f());
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ 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) {
|
||||||
this.timeout(20000);
|
this.timeout(30000);
|
||||||
|
|
||||||
var uglifyjs = '"' + process.argv[0] + '" bin/uglifyjs';
|
var uglifyjs = '"' + process.argv[0] + '" bin/uglifyjs';
|
||||||
var command = uglifyjs + " --self -cm --wrap SpiderUglify -o spidermonkey | " +
|
var command = uglifyjs + " --self -cm --wrap SpiderUglify -o spidermonkey | " +
|
||||||
|
|||||||
Reference in New Issue
Block a user