Search code examples
webpackbabeljsbabel-loader

How do I stop `babel-loader` for webpack from minifying class names?


I have the following in my webpack.config

{
    test: /\.js$/,
    exclude: /node_modules/,
    use:
    { 
        loader: "babel-loader",
        options: {
            presets: [
                ["@babel/preset-env", { 
                    "targets": "last 1 chrome version"
                    }
                ]
            ],
            plugins: ["@babel/plugin-proposal-class-properties", "@babel/plugin-proposal-private-methods"]
        }
    }
}

How do I stop webpack/babel from minifying/mangling class names when built in production mode?


Solution

  • The keep_classnames terser option can do this, see terser Minify options.

    keep_classnames (default: undefined) - pass true to prevent discarding or mangling of class names. Pass a regular expression to only keep class names matching that regex.

    E.g.

    src/mock-link.js:

    export class MockLink {
      toString() {
        return 'mock link'
      }
    }
    

    src/app.js:

    import { MockLink } from './mock-link'
    
    const mockLink = new MockLink();
    console.log(mockLink);
    

    webpack.config.js:

    const path = require('path');
    const TerserPlugin = require("terser-webpack-plugin");
    
    module.exports = {
      mode: 'production',
      entry: './src/app.js',
      output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist'),
      },
      module: {
        rules: [
          {
            test: /\.(?:js|mjs|cjs)$/,
            exclude: /node_modules/,
            use: {
              loader: 'babel-loader',
              options: {
                presets: [
                  ['@babel/preset-env', { targets: "defaults" }]
                ]
              }
            }
          }
        ],
      },
      optimization: {
        minimize: true,
        minimizer: [new TerserPlugin({
          terserOptions: {
            keep_classnames: true
          }
        })],
      }
    };
    

    dist/bundle.js:

    (()=>{"use strict";const n=new class MockLink{toString(){return"mock link"}};console.log(n)})();
    

    If we set the keep_classnames to false, the output of the dist/bundle.js:

    (()=>{"use strict";const n=new class{toString(){return"mock link"}};console.log(n)})();
    

    package versions:

    "devDependencies": {
      "@babel/core": "^7.21.4",
      "@babel/preset-env": "^7.21.4",
      "babel-loader": "^9.1.2",
      "terser-webpack-plugin": "^5.3.7",
      "typescript": "^5.0.4",
      "webpack": "^5.80.0",
      "webpack-cli": "^5.0.2"
    }