[英]Class.name always 'e' for every class after uglify / webpack for production
[英]Angular / Typescript class.name does not work in production build
使用Angular5。遇到class.name属性的怪异问题。 我们在打字稿中具有以下功能:
export class ApiService
{
public list<T>(c: new(values: Object)=> T)
{
var cname = c.name;
....
}
}
现在,如果我在Angular(ng-build)的开发版本中使用此功能,如下所示:
export class Employee()
{
public id:string;
public name: string;
constructor(values: Object = {}) {
Object.assign(this, values);
}
}
并在某处的代码中:
var list = api.list(Employee);
上面的作品,并且在列表函数中,我得到cname ='Employee'
但是,如果我们使用ng build --env = prod来构建此解决方案,则代码将失败,并且将得到cname = undefined。
为什么会发生这种情况,以及如何解决? 不应该在开发版本中编译和工作,在生产中工作的东西吗?
您可能会遇到缩小问题,该问题仅在prod
构建期间发生。 缩小将重命名您的类,以实现最小的输出文件大小。
请参阅此问题和答案以进行相关讨论: Angular-cli:如何忽略类名而使其被缩小
就像上面的答案提到的那样,要配置此选项,您需要ng eject
您的应用程序,这将允许您自定义UglifyJS选项(负责缩小的库),但这也会阻止您使用的一些不错的功能Angular CLI(例如ng build
和ng serve
)。
请参阅此GitHub评论以获取ng eject
的描述: https : //github.com/angular/angular-cli/issues/6302#issuecomment-301220770
生产代码存在相同的问题,其中“ constructor.name”返回一个空字符串。 我的解决方案是装饰所需的类,其中装饰器将在运行时使用任意的类名或通过参数传递的一个类名来重新分配“名称”:这是装饰器:
import "reflect-metadata";
var __global__ClassName__id__ = 0;
export function ClassName(useThisName: string = null) {
return function (target: any) {
if (target.name.length === 0 || useThisName !== null) {
Object.defineProperty(target, "name", {
value: useThisName !== null ? useThisName : `__ClassName__${++__global__ClassName__id__}`,
enumerable: false,
writable: false,
configurable: true
});
}
}
}
和代码看起来像这样:
// generate a dynamic class name
@Decorator.ClassName()
export class PopupMessage{ }
// uses the argument as class name
@Decorator.ClassName("PopupMessage")
export class PopupMessage{ }
// and code will work as usual
var something = new Message.PopupMessage(1);
var samething = (<any>something).constructor.name == Message.PopupMessage.name;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.