使用UglifyJS时,除非keep_fnames
设置为true
,否则功能名称会被修改。例如,以下的Typescript代码:
class Test {}
console.log(Test.name);
编译为JS为:
function Test() {}
console.log(Test.name);
将被解释为:
function t() {}
console.log(t.name);
并将t
而不是test
输出到控制台。
是否有办法(other than using keep_fnames
option)在uglification后保留name
属性? (我不想使用keep_fnames:true
因为它会大大增加捆绑包的大小。
我想到的可能的解决方案:
Test.name = 'Test'
的Webpack插件,但这不会起作用,因为Function.prototype.name
是一个只读属性; design:type
元数据,它只针对属性发出(我认为是因为Function.prototype.name
存在,但我猜猜他们错过了这个边缘案例?)。答案 0 :(得分:2)
在uglification之后有没有办法(除了使用keep_fnames选项)保留name属性...
保持正确名称的唯一机制涉及该名称在输出文件中,因此简短答案为否。如果您想使用prototype.name
,则需要保留该名称。
替代方案将涉及:
prototype.name
的所有用途预先编译为字符串值...我不知道存在但你永远不知道!答案 1 :(得分:2)
正如它解释here,Function.prototype.name
不能在客户端代码中依赖,因为函数原始名称的信息将在缩小过程中被销毁。防止它被重命名是快速而肮脏的修复。
name
在某些浏览器中是只读且不可配置的,因此执行类似
class Test {
static get name() {
return 'Test';
}
}
或
function Test() {}
Object.defineProperty(Test, 'name', { configurable: true, value: 'Test' });
会在大多数浏览器中修复它,但会在其他浏览器中导致模糊的兼容性问题(例如,Android 4.x浏览器)。
执行此操作的正确方法是从不依赖name
在客户端代码中进行调试。至于Node.js和Electron,它取决于代码是否需要进行模糊处理。
如果某个类或函数应存在字符串标识符,则可以选择另一个静态属性名称,例如id
或不受支持的传统displayName
。