Read more

Minifying object properties in JavaScript files

Henning Koch
September 06, 2023Software engineer at makandra GmbH

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.

Illustration web development

Do you need DevOps-experts?

Your development team has a full backlog? No time for infrastructure architecture? Our DevOps team is ready to support you!

  • We build reliable cloud solutions with Infrastructure as code
  • We are experts in security, Linux and databases
  • We support your dev team to perform
Read more Show archive.org snapshot

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
September 06, 2023Software engineer at makandra GmbH
Posted by Henning Koch to makandra dev (2023-09-06 11:09)