Compare commits

..

7 Commits

Author SHA1 Message Date
Alex Lam S.L
87f8a484e6 v2.8.24 2017-05-12 15:47:02 +08:00
Alex Lam S.L
c736834aa4 Merge pull request #1921 from alexlamsl/v2.8.24 2017-05-12 14:58:35 +08:00
olsonpm
9a98513981 add documentation for side_effects & [#@]__PURE__ (#1925) 2017-05-12 12:55:07 +08:00
Alex Lam S.L
f631d6437a avoid arguments and eval in reduce_vars (#1924)
fixes #1922
2017-05-12 12:45:38 +08:00
Alex Lam S.L
aa7e8783f8 fix invalid transform on const (#1919)
- preserve (re)assignment to `const` for runtime error
- suppress `cascade` on `const`, as runtime behaviour is ill-defined
2017-05-12 05:04:28 +08:00
Alex Lam S.L
13e5e33448 document known issues with const (#1916) 2017-05-12 03:36:54 +08:00
kzc
487ae8e3be change harmony references to uglify-es in README (#1902) 2017-05-10 16:38:10 +08:00
7 changed files with 184 additions and 36 deletions

View File

@@ -11,9 +11,10 @@ There's also an
Chrome and probably Safari). Chrome and probably Safari).
#### Note: #### Note:
- 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. - Support for `const` is [present but incomplete](#support-for-const), and may not be
- Node 7 has a known performance regression and runs `uglify-js` twice as slow. transformed properly.
- Those wishing to minify ES2015+ (ES6+) should use the `npm` package [**uglify-es**](https://github.com/mishoo/UglifyJS2/tree/harmony).
Install Install
------- -------
@@ -29,12 +30,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
----- -----
@@ -448,6 +443,11 @@ to set `true`; it's effectively a shortcut for `foo=true`).
- `keep_infinity` -- default `false`. Pass `true` to prevent `Infinity` from - `keep_infinity` -- default `false`. Pass `true` to prevent `Infinity` from
being compressed into `1/0`, which may cause performance issues on Chrome. being compressed into `1/0`, which may cause performance issues on Chrome.
- `side_effects` -- default `false`. Pass `true` to potentially drop functions
marked as "pure". (A function is marked as "pure" via the comment annotation
`/* @__PURE__ */` or `/* #__PURE__ */`)
### The `unsafe` option ### The `unsafe` option
It enables some transformations that *might* break code logic in certain It enables some transformations that *might* break code logic in certain
@@ -983,19 +983,9 @@ The `source_map_options` (optional) can contain the following properties:
[compressor]: http://lisperator.net/uglifyjs/compress [compressor]: http://lisperator.net/uglifyjs/compress
[parser]: http://lisperator.net/uglifyjs/parser [parser]: http://lisperator.net/uglifyjs/parser
#### Harmony #### Support for `const`
If you wish to use the experimental [harmony](https://github.com/mishoo/UglifyJS2/commits/harmony) `const` in `uglify-js@2.x` has function scope and as such behaves much like
branch to minify ES2015+ (ES6+) code please use the following in your `package.json` file: `var` - unlike `const` in ES2015 (ES6) which has block scope. It is recommended
to avoid using `const` for this reason as it will have undefined behavior when
``` run on an ES2015 compatible browser.
"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.

View File

@@ -326,10 +326,14 @@ merge(Compressor.prototype, {
// So existing transformation rules can work on them. // So existing transformation rules can work on them.
node.argnames.forEach(function(arg, i) { node.argnames.forEach(function(arg, i) {
var d = arg.definition(); var d = arg.definition();
if (!node.uses_arguments && d.fixed === undefined) {
d.fixed = function() { d.fixed = function() {
return iife.args[i] || make_node(AST_Undefined, iife); return iife.args[i] || make_node(AST_Undefined, iife);
}; };
mark(d, true); mark(d, true);
} else {
d.fixed = false;
}
}); });
} }
if (node instanceof AST_If || node instanceof AST_DWLoop) { if (node instanceof AST_If || node instanceof AST_DWLoop) {
@@ -414,7 +418,9 @@ merge(Compressor.prototype, {
function reset_def(def) { function reset_def(def) {
def.escaped = false; def.escaped = false;
if (toplevel || !def.global || def.orig[0] instanceof AST_SymbolConst) { if (def.scope.uses_eval) {
def.fixed = false;
} else if (toplevel || !def.global || def.orig[0] instanceof AST_SymbolConst) {
def.fixed = undefined; def.fixed = undefined;
} else { } else {
def.fixed = false; def.fixed = false;
@@ -440,6 +446,14 @@ merge(Compressor.prototype, {
return fixed(); return fixed();
}); });
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++)) {
@@ -1909,6 +1923,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;
@@ -3066,7 +3081,8 @@ merge(Compressor.prototype, {
} }
if (left if (left
&& !(left instanceof AST_SymbolRef && !(left instanceof AST_SymbolRef
&& left.definition().orig[0] instanceof AST_SymbolLambda)) { && (left.definition().orig[0] instanceof AST_SymbolLambda
|| is_reference_const(left)))) {
var parent, field; var parent, field;
var cdr = self.cdr; var cdr = self.cdr;
while (true) { while (true) {

View File

@@ -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": "2.8.23", "version": "2.8.24",
"engines": { "engines": {
"node": ">=0.8.0" "node": ">=0.8.0"
}, },

View File

@@ -1592,3 +1592,49 @@ var_side_effects_3: {
} }
expect_stdout: true expect_stdout: true
} }
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
}

View File

@@ -1064,3 +1064,28 @@ issue_1830_2: {
} }
expect_stdout: "1" expect_stdout: "1"
} }
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
}

View File

@@ -41,22 +41,22 @@ reduce_vars: {
var A = 1; var A = 1;
(function() { (function() {
console.log(-3); console.log(-3);
console.log(-4); console.log(A - 5);
})(); })();
(function f1() { (function f1() {
var a = 2; var a = 2;
console.log(-3); console.log(a - 5);
eval("console.log(a);"); eval("console.log(a);");
})(); })();
(function f2(eval) { (function f2(eval) {
var a = 2; var a = 2;
console.log(-3); console.log(a - 5);
eval("console.log(a);"); eval("console.log(a);");
})(eval); })(eval);
(function() { (function() {
return "yes"; return "yes";
})(); })();
console.log(2); console.log(A + 1);
} }
expect_stdout: true expect_stdout: true
} }
@@ -1732,7 +1732,10 @@ redefine_arguments_3: {
console.log(function() { console.log(function() {
var arguments; var arguments;
return typeof arguments; return typeof arguments;
}(), "number", "undefined"); }(), "number", function(x) {
var arguments = x;
return typeof arguments;
}());
} }
expect_stdout: "object number undefined" expect_stdout: "object number undefined"
} }
@@ -2122,3 +2125,47 @@ issue_1865: {
} }
expect_stdout: true expect_stdout: true
} }
issue_1922_1: {
options = {
evaluate: true,
reduce_vars: true,
unused: true,
}
input: {
console.log(function(a) {
arguments[0] = 2;
return a;
}(1));
}
expect: {
console.log(function(a) {
arguments[0] = 2;
return a;
}(1));
}
expect_stdout: "2"
}
issue_1922_2: {
options = {
evaluate: true,
reduce_vars: true,
unused: true,
}
input: {
console.log(function() {
var a;
eval("a = 1");
return a;
}(1));
}
expect: {
console.log(function() {
var a;
eval("a = 1");
return a;
}(1));
}
expect_stdout: "1"
}

View File

@@ -610,3 +610,27 @@ delete_seq_6: {
} }
expect_stdout: true expect_stdout: true
} }
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
}