Skip to content

Commit

Permalink
improve usability of --mangle-props (#5669)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexlamsl authored Sep 18, 2022
1 parent eb22f01 commit 5ac6ec5
Show file tree
Hide file tree
Showing 8 changed files with 93 additions and 9 deletions.
12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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
Expand Down
9 changes: 6 additions & 3 deletions lib/ast.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions lib/compress.js
Original file line number Diff line number Diff line change
Expand Up @@ -13236,6 +13236,7 @@ Compressor.prototype.compress = function(node) {
optional: self.optional,
expression: expr,
property: property,
quoted: true,
}).optimize(compressor);
}
}
Expand Down
1 change: 1 addition & 0 deletions lib/minify.js
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
2 changes: 1 addition & 1 deletion lib/output.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 2 additions & 0 deletions lib/propmangle.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
4 changes: 3 additions & 1 deletion test/compress.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand Down
71 changes: 68 additions & 3 deletions test/compress/properties.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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: {
Expand Down

0 comments on commit 5ac6ec5

Please sign in to comment.