For an application we need to keep the classname not minified because we use
var className = myObject.constructor.name;
export class myObject{ ... }
when we run
ng build -- pro
the class name gets minified in a random name.
For an application we need to keep the classname not minified because we use
var className = myObject.constructor.name;
export class myObject{ ... }
when we run
ng build -- pro
the class name gets minified in a random name.
Angular cli builder supports NG_BUILD_MANGLE, NG_BUILD_MINIFY, NG_BUILD_BEAUTIFY node environment params (checked in version 8).
You can set them when running npm script in following way:
env NG_BUILD_MANGLE=false NG_BUILD_MINIFY=false NG_BUILD_BEAUTIFY=true ng build --prod
This will result in unminified output, yet tree shaking and other optimizations will still be applied (compared to just turning off optimization).
adding to yantrab's answer for angular 8.2+ using angular-builders
in angular.json
builder: @angular-builders/custom-webpack:browser
options:
"customWebpackConfig": {
"path": "./extra-webpack.config.js",
"mergeStrategies": {
"externals": "replace"
}
},
in extra-webpack.config.js:
module.exports = config => {
config.optimization.minimizer.filter (({constructor: {name}}) => name === 'TerserPlugin')
.forEach (terser => {
terser.options.terserOptions.keep_classnames = true;
});
return config;
};
then either target es5 or es2015 with differential loading disabled per the browserslist discussed here: https://github.com/just-jeb/angular-builders/issues/144#issuecomment-568890065
For Angular 9-12, some of the other answers don't work anymore.
Similar to Rob's answer, we didn't want to worry about maintaining modified versions of @angular-devkit/build-angular, so I instead used ngx-build-plus as our builder in order to introduce a simple plugin to the build process that overrides the Terser config. This works for Angular 9-11.
I created a new file named build-plugin.js:
exports.default = {
pre: function () {
},
config: function (cfg) {
// Override Angular's internal configuration of Terser to preserve class names.
// This won't work if you build multiple (differential) client bundles, so make sure you only target es5 builds in tsconfig.json.
// See https://github.com/just-jeb/angular-builders/issues/144#issuecomment-576424615
cfg.optimization.minimizer.forEach(function (it) {
if (it.constructor.name === 'TerserPlugin') {
it.options.terserOptions["keep_fnames"] = true;
it.options.terserOptions["keep_classnames"] = true;
}
});
return cfg;
},
post: function () {
}
};
Then updated the project's angular.json:
{
"projects": {
"my-project": {
"architect": {
"build": {
"builder": "ngx-build-plus:browser",
"options": {
"plugin": "~build-plugin.js",
...
}
}
}
}
}
...
}
In Angular 12, they've changed the code optimizer from TerserPlugin to JavaScriptOptimizerPlugin for most projects. So just update build-plugin.js to include an override for it as well:
if (it.constructor.name === 'TerserPlugin') {
it.options.terserOptions["keep_fnames"] = true;
it.options.terserOptions["keep_classnames"] = true;
} else if (it.constructor.name === 'JavaScriptOptimizerPlugin') {
it.options.keepNames = true;
}
angular 8 using terser.
this is my config for angular builder :
module.exports = cfg => {
const options = cfg.optimization.minimizer[cfg.optimization.minimizer.length - 1].options.terserOptions;
options.keep_classnames = true;
return cfg;
};
and change terget to es6
It's possible to avoid mangling specific symbols by doing the following:
NG_BUILD_MANGLE=false $NG build --prod ... approach to tell angular to avoid doing any mangling of names.ng add ngx-build-plus
An example of the sort of webpack.partial.js you could use is:
const terser = require('terser-webpack-plugin');
module.exports = {
optimization: {
minimizer: [
new terser.TerserPlugin({
terserOptions: {
compress: false,
mangle: {
reserved: [
"MyClassName1", ...
]
}
}
})
]
}
}
(n.b. make sure you've run npm install --save-dev webpack as well!)
And then amend your build command so it's of this form:
NG_BUILD_MANGLE=false ng build --prod ... --extra-webpack-config webpack.partial.js -o
These two things combined tell the angular build process to avoid mangling and lets your configured instance of TerserPlugin do the mangling at a later stage whilst respecting the classes you want to remain un-mangled.
Building off Andres M's answer, you can disable mangling without ng eject by directly modifying the Angular file that controls the settings for Webpack: node_modules/@angular-devkit/build-angular/src/angular-cli-files/models/webpack-configs/common.js
Note that this will be overwritten whenever @angular-devkit/build-angular is updated, and is not supported by Angular or NPM (and may kill your cat/cause a nuclear armageddon, don't say I didn't warn you!)
I disabled mangling entirely by changing uglifyOptions to uglifyOptions: Object.assign(uglifyOptions, {mangle: false}).
For reference, here's the relevant portion from my modified common.js file
...
new UglifyJSPlugin({
sourceMap: buildOptions.sourceMap,
parallel: true,
cache: true,
uglifyOptions: Object.assign(uglifyOptions, {"mangle": false})
}),
...