Skip to content

Commit 58bd9fa

Browse files
authored
feat: tegg plugin support ModuleConfig (#162)
1 parent 1a24e48 commit 58bd9fa

30 files changed

Lines changed: 308 additions & 20 deletions

File tree

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ plugin/**/dist
2828
plugin/oneapi/test/fixtures/modules/*/oneapi
2929
plugin/dal/test/fixtures/modules/*/dal/
3030

31+
plugin/tegg/test/fixtures/apps/**/*.js
3132
!core/common-util/test/fixtures/**/node_modules
3233
!core/common-util/test/fixtures/**/node_modules/**/*.js
3334
!plugin/*/test/fixtures/**/*.js
@@ -37,6 +38,5 @@ plugin/dal/test/fixtures/modules/*/dal/
3738
!core/eventbus-decorator/src/type.d.ts
3839
!plugin/orm/test/fixtures/prepare.js
3940
!benchmark/**/*.js
40-
plugin/tegg/test/fixtures/apps/**/*.js
4141
!standalone/standalone/test/fixtures/**/node_modules
4242
!standalone/standalone/test/fixtures/**/node_modules/**/*.js

core/common-util/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,6 @@ export * from './src/FSUtil';
66
export * from './src/StackUtil';
77
export * from './src/ProxyUtil';
88
export * from './src/ModuleConfig';
9+
export * from './src/ModuleConfigs';
910
export * from './src/TimerUtil';
1011
export * from './src/RuntimeConfig';

standalone/standalone/src/ModuleConfigs.ts renamed to core/common-util/src/ModuleConfigs.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import { ModuleConfig } from 'egg';
2-
import { ModuleReference } from '@eggjs/tegg-common-util';
1+
import { ModuleConfig, ModuleReference } from './ModuleConfig';
32

43
export interface ModuleConfigHolder {
54
name: string;

core/core-decorator/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export * from './src/decorator/ContextProto';
66
export * from './src/decorator/SingletonProto';
77
export * from './src/decorator/EggQualifier';
88
export * from './src/decorator/MultiInstanceProto';
9+
export * from './src/decorator/ConfigSource';
910

1011
export * from './src/enum/AccessLevel';
1112
export * from './src/enum/ObjectInitType';

standalone/standalone/src/ConfigSource.ts renamed to core/core-decorator/src/decorator/ConfigSource.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { QualifierUtil, EggProtoImplClass } from '@eggjs/tegg';
1+
import { QualifierUtil } from '../util/QualifierUtil';
2+
import { EggProtoImplClass } from '../model/EggPrototypeInfo';
23

34
export const ConfigSourceQualifierAttribute = Symbol.for('Qualifier.ConfigSource');
45

core/tegg/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@ export * from '@eggjs/tegg-background-task';
77
export * as aop from '@eggjs/aop-decorator';
88
export * as orm from '@eggjs/tegg-orm-decorator';
99
export * as schedule from '@eggjs/tegg-schedule-decorator';
10-
export { RuntimeConfig } from '@eggjs/tegg-common-util';
10+
export { RuntimeConfig, ModuleConfigs, ModuleConfigHolder } from '@eggjs/tegg-common-util';

plugin/tegg/app.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,15 @@ import { EggContextHandler } from './lib/EggContextHandler';
99
import { hijackRunInBackground } from './lib/run_in_background';
1010
import { EggQualifierProtoHook } from './lib/EggQualifierProtoHook';
1111
import { LoadUnitMultiInstanceProtoHook } from '@eggjs/tegg-metadata';
12+
import { ConfigSourceLoadUnitHook } from './lib/ConfigSourceLoadUnitHook';
1213

1314
export default class App {
1415
private readonly app: Application;
1516
private compatibleHook?: EggContextCompatibleHook;
1617
private eggContextHandler: EggContextHandler;
1718
private eggQualifierProtoHook: EggQualifierProtoHook;
1819
private loadUnitMultiInstanceProtoHook: LoadUnitMultiInstanceProtoHook;
20+
private configSourceEggPrototypeHook: ConfigSourceLoadUnitHook;
1921

2022
constructor(app: Application) {
2123
this.app = app;
@@ -40,6 +42,10 @@ export default class App {
4042
// wait all file loaded, so app/ctx has all properties
4143
this.eggQualifierProtoHook = new EggQualifierProtoHook(this.app);
4244
this.app.loadUnitLifecycleUtil.registerLifecycle(this.eggQualifierProtoHook);
45+
46+
this.configSourceEggPrototypeHook = new ConfigSourceLoadUnitHook();
47+
this.app.loadUnitLifecycleUtil.registerLifecycle(this.configSourceEggPrototypeHook);
48+
4349
// start load tegg objects
4450
await this.app.moduleHandler.init();
4551
this.compatibleHook = new EggContextCompatibleHook(this.app.moduleHandler);
@@ -55,5 +61,8 @@ export default class App {
5561
if (this.eggQualifierProtoHook) {
5662
this.app.loadUnitLifecycleUtil.deleteLifecycle(this.eggQualifierProtoHook);
5763
}
64+
if (this.configSourceEggPrototypeHook) {
65+
this.app.loadUnitLifecycleUtil.deleteLifecycle(this.configSourceEggPrototypeHook);
66+
}
5867
}
5968
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { LoadUnit, LoadUnitLifecycleContext } from '@eggjs/tegg-metadata';
2+
import {
3+
LifecycleHook,
4+
PrototypeUtil,
5+
QualifierUtil,
6+
ConfigSourceQualifier,
7+
ConfigSourceQualifierAttribute,
8+
} from '@eggjs/tegg';
9+
10+
/**
11+
* Copy from standalone/src/ConfigSourceLoadUnitHook
12+
* Hook for inject moduleConfig.
13+
* Add default qualifier value is current module name.
14+
*/
15+
export class ConfigSourceLoadUnitHook implements LifecycleHook<LoadUnitLifecycleContext, LoadUnit> {
16+
async preCreate(ctx: LoadUnitLifecycleContext, loadUnit: LoadUnit): Promise<void> {
17+
const classList = ctx.loader.load();
18+
for (const clazz of classList) {
19+
const injectObjects = PrototypeUtil.getInjectObjects(clazz);
20+
const moduleConfigObject = injectObjects.find(t => t.objName === 'moduleConfig');
21+
const configSourceQualifier = QualifierUtil.getProperQualifier(clazz, 'moduleConfig', ConfigSourceQualifierAttribute);
22+
if (moduleConfigObject && !configSourceQualifier) {
23+
ConfigSourceQualifier(loadUnit.name)(clazz.prototype, moduleConfigObject.refName);
24+
}
25+
}
26+
}
27+
}

plugin/tegg/lib/EggAppLoader.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,12 @@ import { ObjectUtils } from '@eggjs/tegg-common-util';
1515
import { COMPATIBLE_PROTO_IMPLE_TYPE } from './EggCompatibleProtoImpl';
1616
import { BackgroundTaskHelper } from '@eggjs/tegg-background-task';
1717
import { EggObjectFactory } from '@eggjs/tegg-dynamic-inject-runtime';
18+
import { ModuleConfigLoader } from './ModuleConfigLoader';
1819

19-
export const APP_CLAZZ_BLACK_LIST = [ 'eggObjectFactory' ];
20+
export const APP_CLAZZ_BLACK_LIST = [
21+
'eggObjectFactory',
22+
'moduleConfigs',
23+
];
2024

2125
export const CONTEXT_CLAZZ_BLACK_LIST = [
2226
// just use the app.logger, ctx logger is deprecated.
@@ -29,9 +33,11 @@ export const DEFAULT_CONTEXT_CLAZZ = [
2933

3034
export class EggAppLoader implements Loader {
3135
private readonly app: Application;
36+
private readonly moduleConfigLoader: ModuleConfigLoader;
3237

3338
constructor(app) {
3439
this.app = app;
40+
this.moduleConfigLoader = new ModuleConfigLoader(this.app);
3541
}
3642

3743
private buildClazz(name: string, eggType: EggType): EggProtoImplClass {
@@ -124,11 +130,13 @@ export class EggAppLoader implements Loader {
124130
const allSingletonClazzs = allSingletonClazzNames.map(name => this.buildClazz(name, EggType.APP));
125131
const allContextClazzs = allContextClazzNames.map(name => this.buildClazz(name, EggType.CONTEXT));
126132
const appLoggerClazzs = loggerNames.map(name => this.buildAppLoggerClazz(name));
133+
const moduleConfigList = this.moduleConfigLoader.loadModuleConfigList();
127134

128135
return [
129136
...allSingletonClazzs,
130137
...allContextClazzs,
131138
...appLoggerClazzs,
139+
...moduleConfigList,
132140

133141
// inner helper class list
134142
// TODO: should auto the inner class
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
import {
2+
AccessLevel,
3+
EggProtoImplClass,
4+
EggQualifierAttribute,
5+
EggType,
6+
InitTypeQualifierAttribute,
7+
LoadUnitNameQualifierAttribute, ModuleConfigs,
8+
ObjectInitType,
9+
PrototypeUtil,
10+
QualifierUtil,
11+
ModuleConfigHolder, ConfigSourceQualifierAttribute,
12+
} from '@eggjs/tegg';
13+
import { ModuleConfigUtil } from '@eggjs/tegg/helper';
14+
import { COMPATIBLE_PROTO_IMPLE_TYPE } from './EggCompatibleProtoImpl';
15+
import { Application } from 'egg';
16+
17+
export class ModuleConfigLoader {
18+
constructor(readonly app: Application) {
19+
}
20+
21+
private loadModuleConfigs(moduleConfigMap: Record<string, ModuleConfigHolder>): EggProtoImplClass {
22+
const moduleConfigs = new ModuleConfigs(moduleConfigMap);
23+
const func: EggProtoImplClass = function() {
24+
return moduleConfigs;
25+
} as any;
26+
const name = 'moduleConfigs';
27+
Object.defineProperty(func, 'name', {
28+
value: name,
29+
writable: false,
30+
enumerable: false,
31+
configurable: true,
32+
});
33+
PrototypeUtil.setIsEggPrototype(func);
34+
PrototypeUtil.setFilePath(func, 'mock_file_path');
35+
PrototypeUtil.setProperty(func, {
36+
name,
37+
initType: ObjectInitType.SINGLETON,
38+
accessLevel: AccessLevel.PUBLIC,
39+
protoImplType: COMPATIBLE_PROTO_IMPLE_TYPE,
40+
});
41+
QualifierUtil.addProtoQualifier(func, LoadUnitNameQualifierAttribute, 'app');
42+
QualifierUtil.addProtoQualifier(func, InitTypeQualifierAttribute, ObjectInitType.SINGLETON);
43+
QualifierUtil.addProtoQualifier(func, EggQualifierAttribute, EggType.APP);
44+
return func;
45+
}
46+
47+
loadModuleConfigList(): EggProtoImplClass[] {
48+
const result: EggProtoImplClass[] = [];
49+
const moduleConfigMap: Record<string, ModuleConfigHolder> = {};
50+
for (const reference of this.app.moduleReferences) {
51+
const moduleName = ModuleConfigUtil.readModuleNameSync(reference.path);
52+
const config = ModuleConfigUtil.loadModuleConfigSync(reference.path, undefined, this.app.config.env) || {};
53+
moduleConfigMap[moduleName] = {
54+
name: moduleName,
55+
reference: {
56+
name: moduleName,
57+
path: reference.path,
58+
},
59+
config,
60+
};
61+
62+
const func: EggProtoImplClass = function() {
63+
return config;
64+
} as any;
65+
const name = 'moduleConfig';
66+
Object.defineProperty(func, 'name', {
67+
value: name,
68+
writable: false,
69+
enumerable: false,
70+
configurable: true,
71+
});
72+
PrototypeUtil.setIsEggPrototype(func);
73+
PrototypeUtil.setFilePath(func, 'mock_file_path');
74+
PrototypeUtil.setProperty(func, {
75+
name,
76+
initType: ObjectInitType.SINGLETON,
77+
accessLevel: AccessLevel.PUBLIC,
78+
protoImplType: COMPATIBLE_PROTO_IMPLE_TYPE,
79+
});
80+
QualifierUtil.addProtoQualifier(func, LoadUnitNameQualifierAttribute, 'app');
81+
QualifierUtil.addProtoQualifier(func, InitTypeQualifierAttribute, ObjectInitType.SINGLETON);
82+
QualifierUtil.addProtoQualifier(func, EggQualifierAttribute, EggType.APP);
83+
QualifierUtil.addProtoQualifier(func, ConfigSourceQualifierAttribute, moduleName);
84+
result.push(func);
85+
}
86+
const moduleConfigs = this.loadModuleConfigs(moduleConfigMap);
87+
result.push(moduleConfigs);
88+
return result;
89+
}
90+
}

0 commit comments

Comments
 (0)