improve usability of global_defs in minify() (#1987)
Use `@key` to `parse()` string value as `AST_Node`. fixes #1986
This commit is contained in:
34
README.md
34
README.md
@@ -351,7 +351,7 @@ var result = UglifyJS.minify({"foo.js" : "if (0) else console.log(1);"});
|
|||||||
console.log(JSON.stringify(result.error));
|
console.log(JSON.stringify(result.error));
|
||||||
// {"message":"Unexpected token: keyword (else)","filename":"foo.js","line":1,"col":7,"pos":7}
|
// {"message":"Unexpected token: keyword (else)","filename":"foo.js","line":1,"col":7,"pos":7}
|
||||||
```
|
```
|
||||||
Note: unlike `uglify-js@2.x`, the `3.x` API does not throw errors. To
|
Note: unlike `uglify-js@2.x`, the `3.x` API does not throw errors. To
|
||||||
achieve a similar effect one could do the following:
|
achieve a similar effect one could do the following:
|
||||||
```javascript
|
```javascript
|
||||||
var result = UglifyJS.minify(code, options);
|
var result = UglifyJS.minify(code, options);
|
||||||
@@ -360,7 +360,7 @@ if (result.error) throw result.error;
|
|||||||
|
|
||||||
## Minify options
|
## Minify options
|
||||||
|
|
||||||
- `warnings` (default `false`) — pass `true` to return compressor warnings
|
- `warnings` (default `false`) — pass `true` to return compressor warnings
|
||||||
in `result.warnings`. Use the value `"verbose"` for more detailed warnings.
|
in `result.warnings`. Use the value `"verbose"` for more detailed warnings.
|
||||||
|
|
||||||
- `parse` (default `{}`) — pass an object if you wish to specify some
|
- `parse` (default `{}`) — pass an object if you wish to specify some
|
||||||
@@ -542,7 +542,7 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u
|
|||||||
- `cascade` -- small optimization for sequences, transform `x, x` into `x`
|
- `cascade` -- small optimization for sequences, transform `x, x` into `x`
|
||||||
and `x = something(), x` into `x = something()`
|
and `x = something(), x` into `x = something()`
|
||||||
|
|
||||||
- `collapse_vars` -- Collapse single-use non-constant variables - side
|
- `collapse_vars` -- Collapse single-use non-constant variables - side
|
||||||
effects permitting.
|
effects permitting.
|
||||||
|
|
||||||
- `reduce_vars` -- Improve optimization on variables assigned with and
|
- `reduce_vars` -- Improve optimization on variables assigned with and
|
||||||
@@ -786,7 +786,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:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
var result = uglifyJS.minify(fs.readFileSync("input.js", "utf8"), {
|
var result = UglifyJS.minify(fs.readFileSync("input.js", "utf8"), {
|
||||||
compress: {
|
compress: {
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
global_defs: {
|
global_defs: {
|
||||||
@@ -796,6 +796,32 @@ var result = uglifyJS.minify(fs.readFileSync("input.js", "utf8"), {
|
|||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
|
To replace an identifier with an arbitrary non-constant expression it is
|
||||||
|
necessary to prefix the `global_defs` key with `"@"` to instruct UglifyJS
|
||||||
|
to parse the value as an expression:
|
||||||
|
```javascript
|
||||||
|
UglifyJS.minify("alert('hello');", {
|
||||||
|
compress: {
|
||||||
|
global_defs: {
|
||||||
|
"@alert": "console.log"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).code;
|
||||||
|
// returns: 'console.log("hello");'
|
||||||
|
```
|
||||||
|
|
||||||
|
Otherwise it would be replaced as string literal:
|
||||||
|
```javascript
|
||||||
|
UglifyJS.minify("alert('hello');", {
|
||||||
|
compress: {
|
||||||
|
global_defs: {
|
||||||
|
"alert": "console.log"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).code;
|
||||||
|
// returns: '"console.log"("hello");'
|
||||||
|
```
|
||||||
|
|
||||||
### Using native Uglify AST with `minify()`
|
### Using native Uglify AST with `minify()`
|
||||||
```javascript
|
```javascript
|
||||||
// example: parse only, produce native Uglify AST
|
// example: parse only, produce native Uglify AST
|
||||||
|
|||||||
@@ -87,6 +87,17 @@ function Compressor(options, false_by_default) {
|
|||||||
unused : !false_by_default,
|
unused : !false_by_default,
|
||||||
warnings : false,
|
warnings : false,
|
||||||
}, true);
|
}, true);
|
||||||
|
var global_defs = this.options["global_defs"];
|
||||||
|
if (typeof global_defs == "object") for (var key in global_defs) {
|
||||||
|
if (/^@/.test(key) && HOP(global_defs, key)) {
|
||||||
|
var ast = parse(global_defs[key]);
|
||||||
|
if (ast.body.length == 1 && ast.body[0] instanceof AST_SimpleStatement) {
|
||||||
|
global_defs[key.slice(1)] = ast.body[0].body;
|
||||||
|
} else throw new Error(string_template("Can't handle expression: {value}", {
|
||||||
|
value: global_defs[key]
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
var pure_funcs = this.options["pure_funcs"];
|
var pure_funcs = this.options["pure_funcs"];
|
||||||
if (typeof pure_funcs == "function") {
|
if (typeof pure_funcs == "function") {
|
||||||
this.pure_funcs = pure_funcs;
|
this.pure_funcs = pure_funcs;
|
||||||
|
|||||||
@@ -160,3 +160,17 @@ issue_1801: {
|
|||||||
console.log(!0);
|
console.log(!0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_1986: {
|
||||||
|
options = {
|
||||||
|
global_defs: {
|
||||||
|
"@alert": "console.log",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
alert(42);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(42);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -181,4 +181,19 @@ describe("minify", function() {
|
|||||||
assert.strictEqual(err.col, 12);
|
assert.strictEqual(err.col, 12);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("global_defs", function() {
|
||||||
|
it("should throw for non-trivial expressions", function() {
|
||||||
|
var result = Uglify.minify("alert(42);", {
|
||||||
|
compress: {
|
||||||
|
global_defs: {
|
||||||
|
"@alert": "debugger"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var err = result.error;
|
||||||
|
assert.ok(err instanceof Error);
|
||||||
|
assert.strictEqual(err.stack.split(/\n/)[0], "Error: Can't handle expression: debugger");
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user