Search code examples
vue.jswebpackterser

More extensive mangling terser-webpack-plugin?


Is there a way to thoroughly mangle vue components that have been bundled with webpack?

When applying mangling via terser-webpack-plugin with mangle.properties set to true, then not all of the property names are mangled, for example:

location: {
  lng: -.134281,
  lat:51.513508,
  zoom:13,
  pitch:1,
  bearing:60
}

becomes

location:{
  k:-.134281,
  M:51.513508,
  zoom:13,
  pitch:1,
  V:60
}

Edit

As requested: the relevant portion of the Webpack configuration file, in this case the default vie-cli config with the mangle.properties item manually added:

minimizer: [
      {
        options: {
          test: /\.m?js(\?.*)?$/i,
          chunkFilter: () => true,
          warningsFilter: () => true,
          extractComments: false,
          sourceMap: false,
          cache: true,
          cacheKeys: defaultCacheKeys => defaultCacheKeys,
          parallel: true,
          include: undefined,
          exclude: undefined,
          minify: undefined,
          terserOptions: {
            output: {
              comments: /^\**!|@preserve|@license|@cc_on/i
            },
            compress: {
              arrows: false,
              collapse_vars: false,
              comparisons: false,
              computed_props: false,
              hoist_funs: false,
              hoist_props: false,
              hoist_vars: false,
              inline: false,
              loops: false,
              negate_iife: false,
              properties: false,
              reduce_funcs: false,
              reduce_vars: false,
              switches: false,
              toplevel: false,
              typeofs: false,
              booleans: true,
              if_return: true,
              sequences: true,
              unused: true,
              conditionals: true,
              dead_code: true,
              evaluate: true
            },
            mangle: {
              safari10: true,
              properties: true
            }
          }
        }
      }
    ],

Solution

  • These two properties (zoom, pitch) so happened to be included in the reserved name list, have a look at this default domprops.json file which UglifyJS uses internally during mangling.

    A default exclusion file is provided in tools/domprops.json which should cover most standard JS and DOM properties defined in various browsers. Pass --mangle-props domprops to disable this feature

    If you like to keep this default list, you could do any of the following in the custom minify option of the plugin:

    1. Create your custom reserved name list,
    2. Load up the default list (domprops.json) and pass in a function/filter for removing those unwanted names,
    3. Simply merge these two files if you are sure there is no name conflict.

    webpack.config.js

    {
      optimization: {
        minimizer: [
          new TerserPlugin({
            minify(file, sourceMap) {
              const uglifyJsOptions = {
                mangle: {
                  properties: {
                    reserved: require('your_custom_list')
                  }
    
                  // Or filter them
    
                  properties: {
                    reserved: require('uglify-js/tools/domprops.json')
                      .filter(name => ![
                        'zoom',
                        'pitch'
                      ]
                      .includes(name))
                  }
                }
              };
    
              return require('uglify-js').minify(file, uglifyJsOptions);
            },
          }),
        ],
      },
    }
    

    Also, please mind the similarities between mangle.reserved and mangle.properties.reserved while doing this, as the latter one might be what you need here. Check out the minify option structure.