From 4e2caea817b99587562edb9fa83c22a028dab7a9 Mon Sep 17 00:00:00 2001 From: Gagan Jakhotiya Date: Tue, 22 Oct 2019 19:32:48 +0530 Subject: [PATCH] support for regex based name filtering --- README.md | 11 +++++++++++ lib/minify.js | 5 +++++ lib/scope.js | 3 +++ test/input/name-regex/input.js | 2 ++ test/input/name-regex/output.js | 1 + test/mocha/cli.js | 32 ++++++++++++++++++++++++++++++++ 6 files changed, 54 insertions(+) create mode 100644 test/input/name-regex/input.js create mode 100644 test/input/name-regex/output.js diff --git a/README.md b/README.md index 270f20cb..5ff5144a 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,7 @@ a double dash to prevent input files being used as option arguments: not used. -m, --mangle [options] Mangle names/specify mangler options: `reserved` List of names that should not be mangled. + `regex` Only mangle matched identifiers. --mangle-props [options] Mangle properties/specify mangler options: `builtins` Mangle property names that overlaps with standard JavaScript globals. @@ -219,6 +220,13 @@ comma-separated list of names. For example: to prevent the `require`, `exports` and `$` names from being changed. +If you want to mangle only the names matching a specific regex, use `regex` option. +For example: + + uglifyjs ... -m regex='/^sw/' + +to mangle only names that starts with `sw` + ### CLI mangling property names (`--mangle-props`) **Note:** THIS WILL PROBABLY BREAK YOUR CODE. Mangling property names @@ -783,6 +791,9 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u - `toplevel` (default `false`) -- Pass `true` to mangle names declared in the top level scope. +- `regex` (default `null`) -- Pass a RegExp literal to only mangle names matching + the regular expression. + Examples: ```javascript diff --git a/lib/minify.js b/lib/minify.js index 93f1295e..4800eb1d 100644 --- a/lib/minify.js +++ b/lib/minify.js @@ -107,7 +107,12 @@ function minify(files, options) { properties: false, reserved: [], toplevel: false, + regex: null, }, true); + if (options.mangle.regex !== null && + options.mangle.regex.constructor.name != "RegExp") { + throw "Input is not a RegExp"; + } if (options.mangle.properties) { if (typeof options.mangle.properties != "object") { options.mangle.properties = {}; diff --git a/lib/scope.js b/lib/scope.js index 131235f6..b52da559 100644 --- a/lib/scope.js +++ b/lib/scope.js @@ -386,6 +386,7 @@ function _default_mangler_options(options) { keep_fnames : false, reserved : [], toplevel : false, + regex : null, }); if (!Array.isArray(options.reserved)) options.reserved = []; // Never mangle arguments @@ -450,6 +451,7 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) { function mangle(def) { if (options.reserved.has[def.name]) return; + if (options.regex && !options.regex.test(def.name)) return; def.mangle(options); } @@ -516,6 +518,7 @@ AST_Toplevel.DEFMETHOD("expand_names", function(options) { if (def.global && options.cache) return; if (def.unmangleable(options)) return; if (options.reserved.has[def.name]) return; + if (options.regex && !options.regex.test(def.name)) return; var redef = def.redefined(); var name = redef ? redef.rename || redef.name : next_name(); def.rename = name; diff --git a/test/input/name-regex/input.js b/test/input/name-regex/input.js new file mode 100644 index 00000000..4eb680cc --- /dev/null +++ b/test/input/name-regex/input.js @@ -0,0 +1,2 @@ +var foo = "asasas"; +var _startsWithThis = "dddddd"; \ No newline at end of file diff --git a/test/input/name-regex/output.js b/test/input/name-regex/output.js new file mode 100644 index 00000000..ffdf7971 --- /dev/null +++ b/test/input/name-regex/output.js @@ -0,0 +1 @@ +var foo="asasas";var d="dddddd"; diff --git a/test/mocha/cli.js b/test/mocha/cli.js index 7a484487..9ad58a41 100644 --- a/test/mocha/cli.js +++ b/test/mocha/cli.js @@ -744,4 +744,36 @@ describe("bin/uglifyjs", function() { done(); }).stdin.end(code); }); + it("Should work with --mangle toplevel,regex='/^_startsWith/g;'", function(done) { + var command = uglifyjscmd + " test/input/name-regex/input.js -m toplevel,regex='/^_startsWith/g;'"; + exec(command, function(err, stdout) { + if (err) throw err; + assert.strictEqual(stdout, read("test/input/name-regex/output.js")); + done(); + }); + }); + it("Should work without regex", function(done) { + var command = uglifyjscmd + " test/input/name-regex/input.js -m toplevel"; + exec(command, function(err, stdout) { + if (err) throw err; + assert.strictEqual(stdout, "var d=\"asasas\";var a=\"dddddd\";\n"); + done(); + }); + }); + it("Should give error against non-regex input", function(done) { + var command = uglifyjscmd + " test/input/name-regex/input.js -m toplevel,regex=g"; + exec(command, function(err, stdout, stderr) { + assert.ok(err); + assert.strictEqual(stderr, "ERROR: Input is not a RegExp\n"); + done(); + }); + }); + it("Should give error against invalid input regex", function(done) { + var command = uglifyjscmd + " test/input/name-regex/input.js -m toplevel,regex=//"; + exec(command, function(err, stdout, stderr) { + assert.ok(err); + assert.strictEqual(true, String(stderr).indexOf("not a supported option") != -1); + done(); + }); + }); });