Search code examples
javascriptwebpackbabeljsrollupterser

Terser: Only mangle matched property names from regex


I want to keep ALL my variables and function names, even the private ones, and only mangles the ones that match the regex.

The docs say:

regex (default: null) — Pass a RegExp literal or pattern string to only mangle property matching the regular expression.

But this will also mangles all private const in function scope like so: (keep_fnames and keep_classnames are set to true).

Config:

const terserOptions = {
  compress: {
    defaults: false,
  },
  format: {
    beautify: true,
    comments: "all",
  },
  mangle: {
    keep_fnames: true,
    properties: {
      regex: /^_/,
    },
  },
};

Input:

function myFunc(arg) {
  const keepThisVarName = arg * 2;
  return {
    keepThisProp: keepThisVarName,
    _mangleThisOne: keepThisVarName,
  }
}

Output:

function myFunc(e) {
  const t = 2 * e;
  return {
    keepThisProp: t,
    p: t
  }
}

Expected output:

function myFunc(arg) {
  const keepThisVarName = arg * 2;
  return {
    keepThisProp: keepThisVarName,
    p: keepThisVarName, // '_mangleThisOne' should be mangled
  }
}

Am I missing something or is it simply not possible to prevent Terser to mangle everything he can by default? If not, any ideas how to mangle only variables that match a regular expression and keep the rest of my codebase intact?

Thanks!


Solution

  • Looking at the source, code it doesn't seem possible to prevent mangling private methods when using the mangle option. Terser will always run mangle_private_properties() when mangle is defined.

    if (options.mangle) {
        toplevel.compute_char_frequency(options.mangle);
        toplevel.mangle_names(options.mangle);
        toplevel = mangle_private_properties(toplevel, options.mangle);
    }
    

    https://github.com/terser/terser/blob/a47f29a57b12999c939845781daa7d6f8bdaeff2/lib/minify.js#L264