From 2dbf8bfaadaee2fc7f5de917c038990c4e165b99 Mon Sep 17 00:00:00 2001 From: "Ashley (Scirra)" Date: Wed, 5 Oct 2016 18:02:13 +0100 Subject: [PATCH] CLI, readme and code style updates Add support for --debug-mangling CLI option, describe it in the readme, and update code changes to use consistent style. --- README.md | 18 ++++++++++++++++++ bin/test.js | 5 +++++ bin/uglifyjs | 5 ++++- lib/propmangle.js | 11 +++++------ 4 files changed, 32 insertions(+), 7 deletions(-) create mode 100644 bin/test.js diff --git a/README.md b/README.md index 4f5b21a0..0ab92bfc 100644 --- a/README.md +++ b/README.md @@ -284,6 +284,23 @@ of mangled property names. Using the name cache is not necessary if you compress all your files in a single call to UglifyJS. +#### Debugging property name mangling + +You can also pass `--debug-mangling` in order to mangle property names +without completely obscuring them. For example the property `o.foo` +would mangle to `o._$foo$_` with this option. This allows property mangling +of a large codebase while still being able to debug the code and identify +where mangling is breaking things. + +Note that by default a random number is added to the name per invocation, +e.g. `o._foo$123$_` where `123` is a random number. This is used to ensure +that mangling is still non-deterministic and that independently mangled +scripts are still broken if they access the same properties. If you provide a +name cache (either with `--name-cache` or the `cache` option in the API) then +the random number is removed, producing just `o._$foo$_`. This ensures that +if you correctly share a cache when mangling separate scripts, then they will +work together. + ## Compressor options You need to pass `--compress` (`-c`) to enable the compressor. Optionally @@ -743,6 +760,7 @@ Other options: - `regex` — Pass a RegExp to only mangle certain names (maps to the `--mangle-regex` CLI arguments option) - `ignore_quoted` – Only mangle unquoted property names (maps to the `--mangle-props 2` CLI arguments option) + - `debug` – Mangle names with the original name still present (maps to the `--debug-mangling` CLI arguments option) We could add more options to `UglifyJS.minify` — if you need additional functionality please suggest! diff --git a/bin/test.js b/bin/test.js new file mode 100644 index 00000000..ea864bc0 --- /dev/null +++ b/bin/test.js @@ -0,0 +1,5 @@ +"use strict"; + +let o = {}; +o.foo = "bar"; +console.log(o.foo); \ No newline at end of file diff --git a/bin/uglifyjs b/bin/uglifyjs index 3f0c8254..eb864b6d 100755 --- a/bin/uglifyjs +++ b/bin/uglifyjs @@ -76,6 +76,7 @@ You need to pass an argument to this option to specify the name that your module .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("dump-spidermonkey-ast", "Dump SpiderMonkey AST to stdout.") + .describe("debug-mangling", "Use debug mode for diagnosing property mangling errors.") .alias("p", "prefix") .alias("o", "output") @@ -130,6 +131,7 @@ You need to pass an argument to this option to specify the name that your module .boolean("bare-returns") .boolean("keep-fnames") .boolean("reserve-domprops") + .boolean("debug-mangling") .wrap(80) @@ -425,7 +427,8 @@ async.eachLimit(files, 1, function (file, cb) { cache : cache, only_cache : !ARGS.mangle_props, regex : regex, - ignore_quoted : ARGS.mangle_props == 2 + ignore_quoted : ARGS.mangle_props == 2, + debug : ARGS.debug_mangling }); writeNameCache("props", cache); })(); diff --git a/lib/propmangle.js b/lib/propmangle.js index cf436c47..d18d5a4c 100644 --- a/lib/propmangle.js +++ b/lib/propmangle.js @@ -95,7 +95,7 @@ function mangle_properties(ast, options) { // to be appended to each mangled name for this invocation. If a cache is passed, use an empty // string to correctly simulate using consistent names when caches are passed around. // (Of course this assumes the same cache is being passed - it's good enough for a debug check though.) - var debugCacheName = Math.floor(Math.random() * 1000).toString(); + var debug_cache_name = Math.floor(Math.random() * 1000).toString(); var cache = options.cache; if (cache == null) { @@ -104,9 +104,8 @@ function mangle_properties(ast, options) { props: new Dictionary() }; } - else - { - debugCacheName = ""; + else { + debug_cache_name = ""; } var regex = options.regex; @@ -218,8 +217,8 @@ function mangle_properties(ast, options) { // passed around, otherwise is a random number to ensure separate invocations mangle // differently as they would in practice. // e.g. "foo" -> "_$foo$123$_" (or "_$foo$_" with consistent cache) - if (debug) - return "_$" + name + (debugCacheName ? "$" + debugCacheName : "") + "$_"; + if (debug && can_mangle(name)) + return "_$" + name + (debug_cache_name ? "$" + debug_cache_name : "") + "$_"; var mangled = cache.props.get(name); if (!mangled) {