Skip to content

Commit e0656a4

Browse files
gxklkillagu
andauthored
feat: use app.loader.getTypeFiles to generate module config file names (#213)
<!-- Thank you for your pull request. Please review below requirements. Bug fixes and new features should include tests and possibly benchmarks. Contributors guide: https://github.com/eggjs/egg/blob/master/CONTRIBUTING.md 感谢您贡献代码。请确认下列 checklist 的完成情况。 Bug 修复和新功能必须包含测试,必要时请附上性能测试。 Contributors guide: https://github.com/eggjs/egg/blob/master/CONTRIBUTING.md --> ##### Checklist <!-- Remove items that do not apply. For completed items, change [ ] to [x]. --> - [ ] `npm test` passes - [ ] tests and/or benchmarks are included - [ ] documentation is changed or added - [ ] commit message follows commit guidelines ##### Affected core subsystem(s) <!-- Provide affected core subsystem(s). --> ##### Description of change <!-- Provide a description of the change below this comment. --> <!-- - any feature? - close https://github.com/eggjs/egg/ISSUE_URL --> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Introduced default configuration loading for specific module files. - **Refactor** - Enhanced module configuration management with new methods and asynchronous loading capabilities. - Updated import syntax and added comprehensive tests for configuration loading. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: killa <[email protected]>
1 parent 8411e07 commit e0656a4

File tree

4 files changed

+116
-51
lines changed

4 files changed

+116
-51
lines changed

core/common-util/src/ModuleConfig.ts

Lines changed: 67 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,10 @@ const DEFAULT_READ_MODULE_REF_OPTS = {
2929
};
3030

3131
export class ModuleConfigUtil {
32-
public static moduleYamlPath(modulePath: string, env?: string): string {
33-
if (env) {
34-
return path.join(modulePath, `module.${env}.yml`);
35-
}
36-
return path.join(modulePath, 'module.yml');
37-
}
32+
static configNames: string[] | undefined;
3833

39-
public static moduleJsonPath(modulePath: string, env?: string): string {
40-
if (env) {
41-
return path.join(modulePath, `module.${env}.json`);
42-
}
43-
return path.join(modulePath, 'module.json');
34+
public static setConfigNames(configNames: string[] | undefined) {
35+
ModuleConfigUtil.configNames = configNames;
4436
}
4537

4638
public static readModuleReference(baseDir: string, options?: ReadModuleReferenceOptions): readonly ModuleReference[] {
@@ -205,25 +197,42 @@ export class ModuleConfigUtil {
205197
return ModuleConfigUtil.getModuleName(pkg);
206198
}
207199

208-
public static async loadModuleConfig(moduleDir: string, baseDir?: string, env?: string): Promise<ModuleConfig | undefined> {
209-
moduleDir = ModuleConfigUtil.resolveModuleDir(moduleDir, baseDir);
210-
let defaultConfig = await ModuleConfigUtil.loadModuleYaml(moduleDir);
211-
if (!defaultConfig) {
212-
defaultConfig = await ModuleConfigUtil.loadModuleJson(moduleDir);
213-
}
214-
let envConfig: ModuleConfig | undefined;
200+
public static async loadModuleConfig(moduleDir: string, baseDir?: string, env?: string): Promise<ModuleConfig> {
201+
const modulePath = ModuleConfigUtil.resolveModuleDir(moduleDir, baseDir);
202+
let configNames: string[];
215203
if (env) {
216-
envConfig = await ModuleConfigUtil.loadModuleYaml(moduleDir, env);
217-
if (!envConfig) {
218-
envConfig = await ModuleConfigUtil.loadModuleJson(moduleDir, env);
204+
configNames = [ 'module', `module.${env}` ];
205+
} else {
206+
// assert(ModuleConfigUtil.configNames, 'should setConfigNames before load module config');
207+
configNames = ModuleConfigUtil.configNames || [ 'module' ];
208+
}
209+
210+
const target: ModuleConfig = {};
211+
for (const configName of configNames) {
212+
let config = await ModuleConfigUtil.#loadOne(modulePath, configName);
213+
// both module.yml and module.default.yml are ok for default config
214+
if (configName === 'module.default' && !config) {
215+
config = await ModuleConfigUtil.#loadOne(modulePath, 'module');
216+
}
217+
if (config) {
218+
extend(true, target, config);
219219
}
220220
}
221-
extend(true, defaultConfig, envConfig);
222-
return defaultConfig;
221+
222+
return target;
223223
}
224224

225-
private static async loadModuleJson(moduleDir: string, env?: string): Promise<ModuleConfig | undefined> {
226-
const moduleJsonPath = ModuleConfigUtil.moduleJsonPath(moduleDir, env);
225+
static async #loadOne(moduleDir: string, configName: string): Promise<ModuleConfig | undefined> {
226+
const yamlConfigPath = path.join(moduleDir, `${configName}.yml`);
227+
let config = await ModuleConfigUtil.#loadYaml(yamlConfigPath);
228+
if (!config) {
229+
const jsonConfigPath = path.join(moduleDir, `${configName}.json`);
230+
config = await ModuleConfigUtil.#loadJson(jsonConfigPath);
231+
}
232+
return config;
233+
}
234+
235+
static async #loadJson(moduleJsonPath: string): Promise<ModuleConfig | undefined> {
227236
const moduleJsonPathExists = await FSUtil.fileExists(moduleJsonPath);
228237
if (!moduleJsonPathExists) {
229238
return;
@@ -233,8 +242,7 @@ export class ModuleConfigUtil {
233242
return moduleJson.config;
234243
}
235244

236-
private static async loadModuleYaml(moduleDir: string, env?: string): Promise<ModuleConfig | undefined> {
237-
const moduleYamlPath = ModuleConfigUtil.moduleYamlPath(moduleDir, env);
245+
static async #loadYaml(moduleYamlPath: string): Promise<ModuleConfig | undefined> {
238246
const moduleYamlPathExists = await FSUtil.fileExists(moduleYamlPath);
239247
if (!moduleYamlPathExists) {
240248
return;
@@ -243,24 +251,42 @@ export class ModuleConfigUtil {
243251
return yaml.safeLoad(moduleYamlContent) as ModuleConfigUtil;
244252
}
245253

246-
public static loadModuleConfigSync(moduleDir: string, baseDir?: string, env?: string): ModuleConfig | undefined {
247-
moduleDir = ModuleConfigUtil.resolveModuleDir(moduleDir, baseDir);
248-
let defaultConfig = ModuleConfigUtil.loadModuleYamlSync(moduleDir);
249-
if (!defaultConfig) {
250-
defaultConfig = ModuleConfigUtil.loadModuleJsonSync(moduleDir);
251-
}
252-
let envConfig: ModuleConfig | undefined;
254+
public static loadModuleConfigSync(moduleDir: string, baseDir?: string, env?: string): ModuleConfig {
255+
const modulePath = ModuleConfigUtil.resolveModuleDir(moduleDir, baseDir);
256+
let configNames: string[];
253257
if (env) {
254-
envConfig = ModuleConfigUtil.loadModuleYamlSync(moduleDir, env);
255-
if (!envConfig) {
256-
envConfig = ModuleConfigUtil.loadModuleJsonSync(moduleDir, env);
258+
configNames = [ 'module', `module.${env}` ];
259+
} else {
260+
// assert(ModuleConfigUtil.configNames, 'should setConfigNames before load module config');
261+
configNames = ModuleConfigUtil.configNames || [ 'module' ];
262+
}
263+
264+
const target: ModuleConfig = {};
265+
for (const configName of configNames) {
266+
let config = ModuleConfigUtil.#loadOneSync(modulePath, configName);
267+
// both module.yml and module.default.yml are ok for default config
268+
if (configName === 'module.default' && !config) {
269+
config = ModuleConfigUtil.#loadOneSync(modulePath, 'module');
257270
}
271+
if (config) {
272+
extend(true, target, config);
273+
}
274+
}
275+
276+
return target;
277+
}
278+
279+
static #loadOneSync(moduleDir: string, configName: string): ModuleConfig | undefined {
280+
const yamlConfigPath = path.join(moduleDir, `${configName}.yml`);
281+
let config = ModuleConfigUtil.#loadYamlSync(yamlConfigPath);
282+
if (!config) {
283+
const jsonConfigPath = path.join(moduleDir, `${configName}.json`);
284+
config = ModuleConfigUtil.#loadJsonSync(jsonConfigPath);
258285
}
259-
return extend(true, defaultConfig, envConfig);
286+
return config;
260287
}
261288

262-
private static loadModuleJsonSync(moduleDir: string, env?: string): ModuleConfig | undefined {
263-
const moduleJsonPath = ModuleConfigUtil.moduleJsonPath(moduleDir, env);
289+
static #loadJsonSync(moduleJsonPath: string): ModuleConfig | undefined {
264290
const moduleJsonPathExists = fs.existsSync(moduleJsonPath);
265291
if (!moduleJsonPathExists) {
266292
return;
@@ -270,8 +296,7 @@ export class ModuleConfigUtil {
270296
return moduleJson.config;
271297
}
272298

273-
private static loadModuleYamlSync(moduleDir: string, env?: string): ModuleConfig | undefined {
274-
const moduleYamlPath = ModuleConfigUtil.moduleYamlPath(moduleDir, env);
299+
static #loadYamlSync(moduleYamlPath: string): ModuleConfig | undefined {
275300
const moduleYamlPathExists = fs.existsSync(moduleYamlPath);
276301
if (!moduleYamlPathExists) {
277302
return;

core/common-util/test/ModuleConfig.test.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
1-
import assert from 'node:assert';
1+
import { strict as assert } from 'node:assert';
22
import path from 'node:path';
33
import { ModuleConfigUtil } from '../src/ModuleConfig';
44

55
describe('test/ModuleConfig.test.ts', () => {
66
describe('load yaml config', () => {
7+
afterEach(() => {
8+
ModuleConfigUtil.setConfigNames(undefined);
9+
});
10+
711
it('should work', () => {
812
const config = ModuleConfigUtil.loadModuleConfigSync(path.join(__dirname, './fixtures/modules/foo-yaml'));
913
assert.deepStrictEqual(config, { mysql: { host: '127.0.0.1' } });
@@ -13,6 +17,24 @@ describe('test/ModuleConfig.test.ts', () => {
1317
const config = ModuleConfigUtil.loadModuleConfigSync(path.join(__dirname, './fixtures/modules/dev-module-config'), undefined, 'dev');
1418
assert.deepStrictEqual(config, { mysql: { host: '127.0.0.1', port: 11306 } });
1519
});
20+
21+
it('should load with configNames', async () => {
22+
ModuleConfigUtil.setConfigNames([ 'module.default', 'module.dev' ]);
23+
const config = await ModuleConfigUtil.loadModuleConfig(path.join(__dirname, './fixtures/modules/dev-module-config'));
24+
const configSync = ModuleConfigUtil.loadModuleConfigSync(path.join(__dirname, './fixtures/modules/dev-module-config'));
25+
assert.deepStrictEqual(config, { mysql: { host: '127.0.0.1', port: 11306 } });
26+
assert.deepStrictEqual(configSync, { mysql: { host: '127.0.0.1', port: 11306 } });
27+
});
28+
29+
// it('should throw error without initialization', async () => {
30+
// await assert.rejects(async () => {
31+
// await ModuleConfigUtil.loadModuleConfig(path.join(__dirname, './fixtures/modules/dev-module-config'));
32+
// }, /should setConfigNames before load module config/);
33+
//
34+
// assert.throws(() => {
35+
// ModuleConfigUtil.loadModuleConfigSync(path.join(__dirname, './fixtures/modules/dev-module-config'));
36+
// }, /should setConfigNames before load module config/);
37+
// });
1638
});
1739

1840
describe('load module reference', () => {

plugin/config/app.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
1-
import { Application } from 'egg';
2-
import { ModuleConfigUtil, ModuleReference } from '@eggjs/tegg-common-util';
1+
import type { Application, IBoot } from 'egg';
2+
import { ModuleConfigUtil } from '@eggjs/tegg-common-util';
3+
import type { ModuleReference } from '@eggjs/tegg-common-util';
34
import { ModuleScanner } from './lib/ModuleScanner';
45

5-
export default class App {
6+
export default class App implements IBoot {
67
private readonly app: Application;
78

89
constructor(app: Application) {
910
this.app = app;
11+
const configNames = this.app.loader.getTypeFiles('module');
12+
ModuleConfigUtil.setConfigNames(configNames);
1013
}
1114

1215
configWillLoad() {
@@ -15,6 +18,7 @@ export default class App {
1518
this.app.moduleReferences = moduleScanner.loadModuleReferences();
1619

1720
this.app.moduleConfigs = {};
21+
1822
for (const reference of this.app.moduleReferences) {
1923
const absoluteRef: ModuleReference = {
2024
path: ModuleConfigUtil.resolveModuleDir(reference.path, this.app.baseDir),
@@ -26,8 +30,12 @@ export default class App {
2630
this.app.moduleConfigs[moduleName] = {
2731
name: moduleName,
2832
reference: absoluteRef,
29-
config: ModuleConfigUtil.loadModuleConfigSync(absoluteRef.path, undefined, this.app.config.env) || {},
33+
config: ModuleConfigUtil.loadModuleConfigSync(absoluteRef.path),
3034
};
3135
}
3236
}
37+
38+
async beforeClose() {
39+
ModuleConfigUtil.setConfigNames(undefined);
40+
}
3341
}

standalone/standalone/src/Runner.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
import { ModuleConfigUtil, ModuleReference, ReadModuleReferenceOptions, RuntimeConfig } from '@eggjs/tegg-common-util';
22
import {
3-
EggPrototype, EggPrototypeLifecycleUtil,
3+
EggPrototype,
4+
EggPrototypeLifecycleUtil,
45
LoadUnit,
56
LoadUnitFactory,
6-
LoadUnitLifecycleUtil, LoadUnitMultiInstanceProtoHook,
7+
LoadUnitLifecycleUtil,
8+
LoadUnitMultiInstanceProtoHook,
79
} from '@eggjs/tegg-metadata';
810
import {
911
ContextHandler,
10-
EggContainerFactory, EggContext, EggObjectLifecycleUtil,
12+
EggContainerFactory,
13+
EggContext,
14+
EggObjectLifecycleUtil,
1115
LoadUnitInstance,
1216
LoadUnitInstanceFactory,
1317
ModuleLoadUnitInstance,
@@ -104,6 +108,10 @@ export class Runner {
104108
obj: runtimeConfig,
105109
}];
106110

111+
// load module.yml and module.env.yml by default
112+
if (!ModuleConfigUtil.configNames) {
113+
ModuleConfigUtil.configNames = [ 'module.default', `module.${this.env}` ];
114+
}
107115
for (const reference of this.moduleReferences) {
108116
const absoluteRef = {
109117
path: ModuleConfigUtil.resolveModuleDir(reference.path, this.cwd),
@@ -114,7 +122,7 @@ export class Runner {
114122
this.moduleConfigs[moduleName] = {
115123
name: moduleName,
116124
reference: absoluteRef,
117-
config: ModuleConfigUtil.loadModuleConfigSync(absoluteRef.path, undefined, this.env) || {},
125+
config: ModuleConfigUtil.loadModuleConfigSync(absoluteRef.path),
118126
};
119127
}
120128
for (const moduleConfig of Object.values(this.moduleConfigs)) {
@@ -267,5 +275,7 @@ export class Runner {
267275
MysqlDataSourceManager.instance.clear();
268276
SqlMapManager.instance.clear();
269277
TableModelManager.instance.clear();
278+
// clear configNames
279+
ModuleConfigUtil.setConfigNames(undefined);
270280
}
271281
}

0 commit comments

Comments
 (0)