feat: 添加 @classname 装饰器,修复打包后类名混淆导致 addBusiness 属性绑定失败的问题

This commit is contained in:
dgflash
2026-06-13 18:59:37 +08:00
parent 4fc6652dfd
commit ba64e8d586
3 changed files with 49 additions and 1 deletions

View File

@@ -7,6 +7,7 @@ import { ViewUtil } from '../../core/utils/ViewUtil';
import { ecs } from '../../libs/ecs/ECS';
import type { CompType } from '../../libs/ecs/registry/ECSTypes';
import type { CCBusiness } from './CCBusiness';
import { getClassName } from '../decorator/ClassNameDecorator';
import { GameComponent } from './GameComponent';
import { ECSEntity } from '../../libs/ecs/entity/ECSEntity';
@@ -269,7 +270,8 @@ export abstract class CCEntity extends ecs.Entity {
this.businesss.set(cls, business);
// 将业务逻辑组件直接附加到实体对象身上,方便直接获取
Reflect.set(this, cls.name, business);
// 使用 classname.getName 获取注册名,避免打包压缩后 cls.name 被混淆
Reflect.set(this, getClassName(cls), business);
return business as T;
}

View File

@@ -0,0 +1,37 @@
/**
* 类名注册装饰器
*
* 由于 JS 打包压缩会改变类名(`ctor.name` 被混淆为单字母),
* 使用此装饰器将原始类名保存到构造函数的静态属性上,打包后仍可获取。
*
* @example
* ```typescript
* @classname('B_Account_Login')
* export class B_Account_Login extends CCBusiness<Account> { ... }
*
* // 获取注册名
* getClassName(B_Account_Login); // 'B_Account_Login'
* ```
*/
/** 装饰器写入的静态属性名 */
const CLASS_NAME_KEY = 'CLASS_NAME';
/**
* 类装饰器工厂:注册类名,防止打包压缩后 `ctor.name` 被混淆。
* @param name 类注册名(须与源码中的类名一致)
*/
export function classname(name: string): ClassDecorator {
return function (ctor: Function): void {
(ctor as any)[CLASS_NAME_KEY] = name;
};
}
/**
* 获取类的注册名,未注册时回退到 `ctor.name`。
* @param ctor 类构造函数
* @returns 注册名或原始类名
*/
export function getClassName(ctor: Function): string {
return (ctor as any)[CLASS_NAME_KEY] || ctor.name;
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "8f61f8d6-9de0-4f33-bff6-d4946105cc11",
"files": [],
"subMetas": {},
"userData": {}
}