DEV Community

Cover image for How to minify private methods in a TypeScript class?
Przemyslaw Jan Beigert
Przemyslaw Jan Beigert

Posted on • Edited on

2

How to minify private methods in a TypeScript class?

Introduction

As you may notice during minification your long and descriptive variable names are changed into e.g.: "a", "rd", "xd". However, when you minify class names of methods stay the same:

class Cls {
  method() {
  }
}

const cls = new Cls();
cls.method();
Enter fullscreen mode Exit fullscreen mode

Will be compiled into

"use strict";(()=>{var c=class{method(){}},e=new c;e.method();})();
Enter fullscreen mode Exit fullscreen mode

Is logical because method has been used in other scripts. But what about private methods?

class Cls {
  public publicMethod() {
    this.privateMethod()
  }
  private privateMethod() {}
}

const cls = new Cls();
cls.publicMethod();
Enter fullscreen mode Exit fullscreen mode

This code with be compiled into:

"use strict";(()=>{var t=class{publicMethod(){this.privateMethod()}privateMethod(){}},e=new t;e.publicMethod();})();
Enter fullscreen mode Exit fullscreen mode

The private method stays the same. Is logical cause code is firstly transpile into JavaScript and then minified. During transpiration information about method privacy will be lost.

Terser

Terser is JavaScript compressor that can minified specific method names.

// terser.config.js
const fs = require('fs');
const terser = require('terser');

(async () => {
    const file = fs.readFileSync('index.js', 'utf8')
    const {code} = await terser.minify(file, {
        mangle: {
            properties: {
                regex: `^(privateMethod)$`,
            },
        },
    });
    fs.writeFileSync('index.js', code)
})();
Enter fullscreen mode Exit fullscreen mode

This code will create something like this:

"use strict";(new class{publicMethod(){this.t()}t(){}}).publicMethod();
Enter fullscreen mode Exit fullscreen mode

Great success? Not yet. We can not manually paste every private method to the config file.

Find all private method

We can use bash to find all names of private methods.

  1. Print all TS files
cat src/**/*.ts
Enter fullscreen mode Exit fullscreen mode
  1. Filter lines by pattern private methodName(...) {
grep -E "^  private (.*?)\("
Enter fullscreen mode Exit fullscreen mode

You can use prettier to be sure that all methods are formatted in the same way.

  1. Map lines like with private methodsName( into methodName by
awk '{split($2,a,"("); print a[1]}'
Enter fullscreen mode Exit fullscreen mode
  1. Join each method with | separator by:
tr '\n' '|'
Enter fullscreen mode Exit fullscreen mode
  1. Merge it with bash pipes:
cat src/**/*.ts | egrep "  private (.*?)\(" | awk '{split($2,a,"("); print a[1]}' | tr '\n' '|'
Enter fullscreen mode Exit fullscreen mode

The output should looks like this: privateMethod|privateMethod1|privateMethod2. It exactly the same that what we can paste to regex in the terser.config.

Fix collision

Unfortunately is public method will have the same name like a private one, both will be minified. How to fix that? Use previous script to find all public methods then just filter in out in the terser.config.js

const methodsToMinify = privateMethods
  .split('|')
  .filter(item => !publicMethods.includes(item))
  .join('|');
Enter fullscreen mode Exit fullscreen mode

Result

In my project helped me reduce bundle size by around 11%. It doesn't sound impressive, however applying this solution is relatively fast

Sentry image

Hands-on debugging session: instrument, monitor, and fix

Join Lazar for a hands-on session where you’ll build it, break it, debug it, and fix it. You’ll set up Sentry, track errors, use Session Replay and Tracing, and leverage some good ol’ AI to find and fix issues fast.

RSVP here →

Top comments (0)

AWS Security LIVE!

Join us for AWS Security LIVE!

Discover the future of cloud security. Tune in live for trends, tips, and solutions from AWS and AWS Partners.

Learn More

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay