Minifying object properties in JavaScript files

Posted . Visible to the public. Repeats.

An introduction to mangling

When you minify ("compress", "optimize") your JavaScript for production, the names of your functions and variables will be renamed for brevity. This process is often called mangling.

E.g. if this is your source code:

function function1() {
  function2()
}

After mangling it would look like this:

function a() {
  b()
}

Object properties are not mangled by default

Minfiers never mangle properties by default, as this can be an unsafe transformation. This leads to larger file sizes if your code uses a lot of classes. That effect is still noticable after gzip compression.

For example, a mangler won't be able to shorten any name in the class below. The names property, publicMethod and privateMethod will appear in the compressed source verbatim:

class Klass {

  constructor(arg) {
    this.property = arg
  }

  publicMethod() {
    if (this.privateMethod()) {
      // ...
    }
  }
  
  privateMethod() {
    return this.property > 10
  }

}

Mangling private properties

While you can tell your minifier to mangle all object properties, this will probably break your code. However, a safe-enough transformation is to mangle private methods and fields instead.

For this the minifier must distinguish between private and public properties. A common convention is to prefix internal properties with an underscore character:

class Klass {

  constructor(arg) {
    this._property = arg
  }

  publicMethod() {
    if (this._privateMethod()) {
      // ...
    }
  }
  
  _privateMethod() {
    return this._property > 10
  }

}

You may also use private class fields Show archive.org snapshot and prefix internal properties with an hash character:

class Klass {

  #property

  constructor(arg) {
    this.#property = arg
  }

  publicMethod() {
    if (this.#privateMethod()) {
      // ...
    }
  }
  
  #privateMethod() {
    return this.#property > 10
  }

}

Configuring esbuild

To configure esbuild to mangle private properties, make a change to your esbuild.config.js:

await esbuild.build({
  ...,
  minify: true,
  mangleProps: /^[_#]/,
})

Configuring Webpack

To configure Webpack to mangle private properties, make a change to your Terser Show archive.org snapshot configuration in webpack.config.js:

{
  ...
  optimization: {
    minimize: true,
    minimizer: [
      new TerserPlugin({
        terserOptions: {
          ...,
          mangle: {
            properties: {
              regex: /^[_#]/
            }
          }
        }
      })
    ]
  }
}

Configuring Webpacker (Rails)

To configure Webpack to mangle private properties, make a change to your Terser Show archive.org snapshot configuration in config/webpack/production.js:

const webpackConfig = require('./environment')
const TerserPlugin = require('terser-webpack-plugin')
terser = webpackConfig.optimization.minimizer.find(plugin => (plugin instanceof TerserPlugin))
terser.options.terserOptions.mangle.properties = { regex: /^[_#]/ }
module.exports = webpackConfig
Henning Koch
Last edit
Henning Koch
License
Source code in this card is licensed under the MIT License.
Posted by Henning Koch to makandra dev (2023-09-06 09:09)