4

I'm trying to configure my Angular 8 project build to keep functions and classes names (I need my classes names to use reflexion and other class name based stuff). To manage this, I use @angular-builders/custom-webpack which allows to override webpack config.

"architect": {
    "build": {
        "builder": "@angular-builders/custom-webpack:browser",
        "options": {
            "customWebpackConfig": {
                "path": "./extra-webpack.config.js",
                "mergeStrategies": {
                    "externals": "replace",
                }
            },

My extra-webpack.config.js:

console.log('Custom webpack config');
const TerserPlugin = require('terser-webpack-plugin');

module.exports = {
    optimization: {
        minimizer: [
            new TerserPlugin({
                terserOptions: {
                    keep_classnames: true,
                    keep_fnames: true,
                }
            })
        ]
    }
};

As said on the Terser documentation, keep_classnames is used to keep classes names and keep_fnames is used to keep functions names.

The problem is that my classes names and my functions names are gone, I cannot find them on the main.XXXX.js build file, and my app doesn't work because the reflexion doesn't works.

I'm sure my extra-webpack.config.js is not ignored because I can see the "Custom webpack config" log on my console.

Should I configure something else to keep my functions and classes names?

Ben
  • 3,972
  • 8
  • 43
  • 82

1 Answers1

0

You can override it, I saved myself 50s compiling time in production although I would suggest to use it only for debugging. You have to override the customWebpackConfig also for the prodbuild like this:

"production": {
          "customWebpackConfig": {
            "path": "./webpack.config.js"
          },
          "fileReplacements": [
            {
              "replace": "/apps/shared/src/environments/environment.ts",
              "with": "/apps/shared/src/environments/environment.prod.ts"
            }
          ],
          "optimization": true,
          "outputHashing": "none",
          "deleteOutputPath": false,
          "extractLicenses": false,
          "statsJson": false,
          "sourceMap": false,
          "extractCss": true,
          "namedChunks": false,
          "vendorChunk": true,
          "buildOptimizer": true,
          "watch": false,
          "budgets": [
            {
              "type": "initial",
              "maximumWarning": "12mb",
              "maximumError": "15mb"
            },
            {
              "type": "anyComponentStyle",
              "maximumWarning": "6kb",
              "maximumError": "10kb"
            }
          ]
        },

also in your webpack config you can do it like this:

optimization: {
concatenateModules: false,
minimizer: [
  new TerserPlugin({
    terserOptions: {
      keep_classnames: environment.optimizeTerser ? true : '/./',
      keep_fnames: environment.optimizeTerser ? true : '/./',
    },
  }),
],
},

According to this Article its not good setting it to true out of obious reasons: https://medium.com/@omril321/fixing-overly-aggressive-optimization-with-terser-f07309761b50

Maintaining the bundle size It wasn’t good enough, we still wanted our bundle to be minified as much as possible. If we used “keep_fnames: true” then our function names wouldn’t be minified, thus our bundle size would increase. TerserPlugin accepts regex as a param to keep_fnames. We used the regex “keep_fnames: /./” which means — if the function has a name of 1 character, don’t change its name (what were you planning to do with it anyway?) This way the problem was solved, while keeping the bundle size to a minimum.

Taslim Oseni
  • 6,086
  • 10
  • 44
  • 69
forestfly
  • 11
  • 3