Add a mode to only mangle unquoted property names

This commit is contained in:
Shrey Banga 2016-06-10 11:55:52 -07:00
parent 2e22da589c
commit 6f3fea60d2
4 changed files with 56 additions and 11 deletions

View File

@ -133,7 +133,11 @@ The available options are:
--reserved-file File containing reserved names --reserved-file File containing reserved names
--reserve-domprops Make (most?) DOM properties reserved for --reserve-domprops Make (most?) DOM properties reserved for
--mangle-props --mangle-props
--mangle-props Mangle property names --mangle-props Mangle property names (default `0`). Set to
`true` or `1` to mangle all property names. Set
to `1` to only mangle unquoted property names.
Use the `keep_quoted_props` beautifier option to
preserve the quotes around property names.
--mangle-regex Only mangle property names matching the regex --mangle-regex Only mangle property names matching the regex
--name-cache File to hold mangled names mappings --name-cache File to hold mangled names mappings
--pure-funcs List of functions that can be safely removed if --pure-funcs List of functions that can be safely removed if

View File

@ -69,7 +69,7 @@ You need to pass an argument to this option to specify the name that your module
.describe("quotes", "Quote style (0 - auto, 1 - single, 2 - double, 3 - original)") .describe("quotes", "Quote style (0 - auto, 1 - single, 2 - double, 3 - original)")
.describe("reserved-file", "File containing reserved names") .describe("reserved-file", "File containing reserved names")
.describe("reserve-domprops", "Make (most?) DOM properties reserved for --mangle-props") .describe("reserve-domprops", "Make (most?) DOM properties reserved for --mangle-props")
.describe("mangle-props", "Mangle property names") .describe("mangle-props", "Mangle property names (0 - disabled, 1 - mangle all properties, 2 - mangle unquoted properies)")
.describe("mangle-regex", "Only mangle property names matching the regex") .describe("mangle-regex", "Only mangle property names matching the regex")
.describe("name-cache", "File to hold mangled names mappings") .describe("name-cache", "File to hold mangled names mappings")
.describe("pure-funcs", "List of functions that can be safely removed if their return value is not used") .describe("pure-funcs", "List of functions that can be safely removed if their return value is not used")
@ -125,7 +125,6 @@ You need to pass an argument to this option to specify the name that your module
.boolean("noerr") .boolean("noerr")
.boolean("bare-returns") .boolean("bare-returns")
.boolean("keep-fnames") .boolean("keep-fnames")
.boolean("mangle-props")
.boolean("reserve-domprops") .boolean("reserve-domprops")
.wrap(80) .wrap(80)
@ -388,6 +387,10 @@ async.eachLimit(files, 1, function (file, cb) {
TOPLEVEL = TOPLEVEL.wrap_enclose(arg_parameter_list); TOPLEVEL = TOPLEVEL.wrap_enclose(arg_parameter_list);
} }
if (ARGS.mangle_props === true) {
ARGS.mangle_props = 1;
}
if (ARGS.mangle_props || ARGS.name_cache) (function(){ if (ARGS.mangle_props || ARGS.name_cache) (function(){
var reserved = RESERVED ? RESERVED.props : null; var reserved = RESERVED ? RESERVED.props : null;
var cache = readNameCache("props"); var cache = readNameCache("props");
@ -401,10 +404,11 @@ async.eachLimit(files, 1, function (file, cb) {
} }
TOPLEVEL = UglifyJS.mangle_properties(TOPLEVEL, { TOPLEVEL = UglifyJS.mangle_properties(TOPLEVEL, {
reserved : reserved, reserved : reserved,
cache : cache, cache : cache,
only_cache : !ARGS.mangle_props, only_cache : !ARGS.mangle_props,
regex : regex regex : regex,
ignore_quoted : ARGS.mangle_props == 2
}); });
writeNameCache("props", cache); writeNameCache("props", cache);
})(); })();

View File

@ -65,7 +65,8 @@ function mangle_properties(ast, options) {
reserved : null, reserved : null,
cache : null, cache : null,
only_cache : false, only_cache : false,
regex : null regex : null,
ignore_quoted : false
}); });
var reserved = options.reserved; var reserved = options.reserved;
@ -81,6 +82,7 @@ function mangle_properties(ast, options) {
} }
var regex = options.regex; var regex = options.regex;
var ignore_quoted = options.ignore_quoted;
var names_to_mangle = []; var names_to_mangle = [];
var unmangleable = []; var unmangleable = [];
@ -88,11 +90,13 @@ function mangle_properties(ast, options) {
// step 1: find candidates to mangle // step 1: find candidates to mangle
ast.walk(new TreeWalker(function(node){ ast.walk(new TreeWalker(function(node){
if (node instanceof AST_ObjectKeyVal) { if (node instanceof AST_ObjectKeyVal) {
add(node.key); if (!(ignore_quoted && node.quote))
add(node.key);
} }
else if (node instanceof AST_ObjectProperty) { else if (node instanceof AST_ObjectProperty) {
// setter or getter, since KeyVal is handled above // setter or getter, since KeyVal is handled above
add(node.key.name); if (!(ignore_quoted && node.key.quote))
add(node.key.name);
} }
else if (node instanceof AST_Dot) { else if (node instanceof AST_Dot) {
if (this.parent() instanceof AST_Assign) { if (this.parent() instanceof AST_Assign) {
@ -101,7 +105,8 @@ function mangle_properties(ast, options) {
} }
else if (node instanceof AST_Sub) { else if (node instanceof AST_Sub) {
if (this.parent() instanceof AST_Assign) { if (this.parent() instanceof AST_Assign) {
addStrings(node.property); if (!(ignore_quoted && node.property.quote))
addStrings(node.property);
} }
} }
})); }));

View File

@ -72,3 +72,35 @@ evaluate_length: {
a = ("foo" + b).length; a = ("foo" + b).length;
} }
} }
mangle_properties: {
mangle_props = {
ignore_quoted: false
};
input: {
a["foo"] = "bar";
a.color = "red";
x = {"bar": 10};
}
expect: {
a["a"] = "bar";
a.b = "red";
x = {c: 10};
}
}
mangle_unquoted_properties: {
mangle_props = {
ignore_quoted: true
};
input: {
a["foo"] = "bar";
a.color = "red";
x = {"bar": 10};
}
expect: {
a["foo"] = "bar";
a.a = "red";
x = {"bar": 10};
}
}