improve usability of --mangle-props (#5669)
This commit is contained in:
12
README.md
12
README.md
@@ -327,7 +327,7 @@ unquoted style (`o.foo`). Example:
|
||||
// stuff.js
|
||||
var o = {
|
||||
"foo": 1,
|
||||
bar: 3
|
||||
bar: 3,
|
||||
};
|
||||
o.foo += o.bar;
|
||||
console.log(o.foo);
|
||||
@@ -339,6 +339,16 @@ $ uglifyjs stuff.js --mangle-props keep_quoted -c -m
|
||||
var o={foo:1,o:3};o.foo+=o.o,console.log(o.foo);
|
||||
```
|
||||
|
||||
If the minified output will be processed again by UglifyJS, consider specifying
|
||||
`keep_quoted_props` so the same property names are preserved:
|
||||
|
||||
```bash
|
||||
$ uglifyjs stuff.js --mangle-props keep_quoted -c -m -O keep_quoted_props
|
||||
```
|
||||
```javascript
|
||||
var o={"foo":1,o:3};o.foo+=o.o,console.log(o.foo);
|
||||
```
|
||||
|
||||
### Debugging property name mangling
|
||||
|
||||
You can also pass `--mangle-props debug` in order to mangle property names
|
||||
|
||||
@@ -1519,7 +1519,7 @@ var AST_New = DEFNODE("New", null, {
|
||||
var AST_Sequence = DEFNODE("Sequence", "expressions", {
|
||||
$documentation: "A sequence expression (comma-separated expressions)",
|
||||
$propdoc: {
|
||||
expressions: "[AST_Node*] array of expressions (at least two)"
|
||||
expressions: "[AST_Node*] array of expressions (at least two)",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return all_equals(this.expressions, node.expressions);
|
||||
@@ -1568,8 +1568,11 @@ var AST_PropAccess = DEFNODE("PropAccess", "expression optional property termina
|
||||
},
|
||||
});
|
||||
|
||||
var AST_Dot = DEFNODE("Dot", null, {
|
||||
var AST_Dot = DEFNODE("Dot", "quoted", {
|
||||
$documentation: "A dotted property access expression",
|
||||
$propdoc: {
|
||||
quoted: "[boolean] whether property is transformed from a quoted string",
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1618,7 +1621,7 @@ var AST_Unary = DEFNODE("Unary", "operator expression", {
|
||||
$documentation: "Base class for unary expressions",
|
||||
$propdoc: {
|
||||
operator: "[string] the operator",
|
||||
expression: "[AST_Node] expression that this unary operator applies to"
|
||||
expression: "[AST_Node] expression that this unary operator applies to",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.operator == node.operator
|
||||
|
||||
@@ -13236,6 +13236,7 @@ Compressor.prototype.compress = function(node) {
|
||||
optional: self.optional,
|
||||
expression: expr,
|
||||
property: property,
|
||||
quoted: true,
|
||||
}).optimize(compressor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -205,6 +205,7 @@ function minify(files, options) {
|
||||
toplevel.mangle_names(options.mangle);
|
||||
}
|
||||
if (timings) timings.properties = Date.now();
|
||||
if (quoted_props) reserve_quoted_keys(toplevel, quoted_props);
|
||||
if (options.mangle && options.mangle.properties) mangle_properties(toplevel, options.mangle.properties);
|
||||
if (options.parse.expression) toplevel = toplevel.unwrap_expression();
|
||||
if (timings) timings.output = Date.now();
|
||||
|
||||
@@ -1517,7 +1517,7 @@ function OutputStream(options) {
|
||||
var expr = self.expression;
|
||||
expr.print(output);
|
||||
var prop = self.property;
|
||||
if (output.option("ie") && RESERVED_WORDS[prop]) {
|
||||
if (output.option("ie") && RESERVED_WORDS[prop] || self.quoted && output.option("keep_quoted_props")) {
|
||||
if (self.optional) output.print("?.");
|
||||
output.with_square(function() {
|
||||
output.add_mapping(self.end);
|
||||
|
||||
@@ -126,6 +126,8 @@ function reserve_quoted_keys(ast, reserved) {
|
||||
ast.walk(new TreeWalker(function(node) {
|
||||
if (node instanceof AST_ClassProperty) {
|
||||
if (node.start && node.start.quote) add(node.key);
|
||||
} else if (node instanceof AST_Dot) {
|
||||
if (node.quoted) add(node.property);
|
||||
} else if (node instanceof AST_ObjectProperty) {
|
||||
if (node.start && node.start.quote) add(node.key);
|
||||
} else if (node instanceof AST_Sub) {
|
||||
|
||||
@@ -307,8 +307,9 @@ function test_case(test) {
|
||||
warnings_emitted.push(text);
|
||||
}, /"INFO: /.test(expected_warnings));
|
||||
}
|
||||
var quoted_props;
|
||||
if (test.mangle && test.mangle.properties && test.mangle.properties.keep_quoted) {
|
||||
var quoted_props = test.mangle.properties.reserved;
|
||||
quoted_props = test.mangle.properties.reserved;
|
||||
if (!Array.isArray(quoted_props)) quoted_props = [];
|
||||
test.mangle.properties.reserved = quoted_props;
|
||||
U.reserve_quoted_keys(input, quoted_props);
|
||||
@@ -323,6 +324,7 @@ function test_case(test) {
|
||||
if (test.mangle) {
|
||||
output.compute_char_frequency(test.mangle);
|
||||
output.mangle_names(test.mangle);
|
||||
if (quoted_props) U.reserve_quoted_keys(input, quoted_props);
|
||||
if (test.mangle.properties) U.mangle_properties(output, test.mangle.properties);
|
||||
}
|
||||
var output_code = make_code(output, output_options, test.expression);
|
||||
|
||||
@@ -353,6 +353,68 @@ mangle_debug_suffix_keep_quoted: {
|
||||
}
|
||||
}
|
||||
|
||||
keep_substituted_property: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
properties: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
mangle = {
|
||||
properties: {
|
||||
keep_quoted: true,
|
||||
},
|
||||
}
|
||||
input: {
|
||||
var o = { p: [] };
|
||||
function f(b) {
|
||||
return o[b];
|
||||
}
|
||||
function g() {
|
||||
var a = "p";
|
||||
return o[a] === f(a);
|
||||
}
|
||||
console.log(g() ? "PASS" : "FAIL");
|
||||
}
|
||||
expect: {
|
||||
var o = { p: [] };
|
||||
function f(n) {
|
||||
return o[n];
|
||||
}
|
||||
function g() {
|
||||
var n = "p";
|
||||
return o.p === f(n);
|
||||
}
|
||||
console.log(g() ? "PASS" : "FAIL");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
keep_substituted_property_quotes: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
properties: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
beautify = {
|
||||
keep_quoted_props: true,
|
||||
}
|
||||
input: {
|
||||
function f(o) {
|
||||
var a = "p";
|
||||
return o[a];
|
||||
}
|
||||
console.log(f({ p: "PASS" }));
|
||||
}
|
||||
expect: {
|
||||
function f(o) {
|
||||
var a = "p";
|
||||
return o["p"];
|
||||
}
|
||||
console.log(f({ p: "PASS" }));
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
first_256_chars_as_properties: {
|
||||
beautify = {
|
||||
ascii_only: true,
|
||||
@@ -899,12 +961,15 @@ issue_2256: {
|
||||
},
|
||||
}
|
||||
input: {
|
||||
({ "keep": 1 });
|
||||
g.keep = g.change;
|
||||
({ "keep": 42 });
|
||||
global.keep = global.change;
|
||||
console.log(keep);
|
||||
}
|
||||
expect: {
|
||||
g.keep = g.g;
|
||||
global.keep = global.l;
|
||||
console.log(keep);
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
lhs_prop_1: {
|
||||
|
||||
Reference in New Issue
Block a user