When using UglifyJS, function names are mangled, unless keep_fnames
is set to true
. For example, the following Typescript code:
class Test {}
console.log(Test.name);
compiled to JS as:
function Test() {}
console.log(Test.name);
will be uglified to:
function t() {}
console.log(t.name);
and output t
instead of test
to the console.
Is there a way (other than using keep_fnames
option) to preserve the name
property after uglification ? (I don't want to use keep_fnames:true
because it increases the bundle size quite a lot.
Possible solutions I thought of:
Test.name = 'Test'
, but this won't work as Function.prototype.name
is a read only property;design:type
metadata is not emitted for classes, it's only emitted for properties (which I believe is because Function.prototype.name
exists, but I guess they missed this edge case ?).As it's explained here, Function.prototype.name
cannot be relied on in client-side code, because the information on function original name will be destroyed with minification process. Preventing it from being renamed is quick-and-dirty fix.
name
is read-only and non-configurable in some browsers, so doing something like
class Test {
static get name() {
return 'Test';
}
}
or
function Test() {}
Object.defineProperty(Test, 'name', { configurable: true, value: 'Test' });
will fix it in most browsers but result in obscure compatibility problems in rest of them (for example, Android 4.x browser).
The proper way to do this is to never rely on name
in client-side code for anything but debugging. As for Node.js and Electron, it depends on whether the code needs to be obfuscated.
If string identifier should exist for a class or a function, another static property name can be picked, e.g. id
or unsupported yet conventional displayName
.
Is there a way (other than using keep_fnames option) to preserve the name property after uglification...
The only mechanism to keep the correct name involves that name being in the output file, so the short answer is no. If you want to use prototype.name
you need to leave that name be.
The alternatives would involve either:
prototype.name
with the string value... I'm not aware that one exists but you never know!If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With