Skip to content

Commit

Permalink
feat: use app.loader.getTypeFiles to generate module config file names
Browse files Browse the repository at this point in the history
  • Loading branch information
gxkl committed Apr 17, 2024
1 parent 5ad6b48 commit d034ed9
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 5 deletions.
82 changes: 82 additions & 0 deletions core/common-util/src/ModuleConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ const DEFAULT_READ_MODULE_REF_OPTS = {
};

export class ModuleConfigUtil {
static configNames: string[] | undefined;

public static setConfigNames(configNames: string[] | undefined) {
ModuleConfigUtil.configNames = configNames;
}

public static moduleYamlPath(modulePath: string, env?: string): string {
if (env) {
return path.join(modulePath, `module.${env}.yml`);
Expand Down Expand Up @@ -205,6 +211,26 @@ export class ModuleConfigUtil {
return ModuleConfigUtil.getModuleName(pkg);
}

public static async load(moduleDir: string, baseDir?: string): Promise<ModuleConfig> {
const modulePath = ModuleConfigUtil.resolveModuleDir(moduleDir, baseDir);
assert(ModuleConfigUtil.configNames, 'should setConfigNames before load module config');

const target: ModuleConfig = {};
for (const configName of ModuleConfigUtil.configNames) {
let config = await ModuleConfigUtil.#loadOne(modulePath, configName);
// both module.yml and module.default.yml are ok for default config
if (configName === 'module.default' && !config) {
config = await ModuleConfigUtil.#loadOne(modulePath, 'module');
}
if (config) {
extend(true, target, config);
}
}

return target;
}

// @deprecated use load instead
public static async loadModuleConfig(moduleDir: string, baseDir?: string, env?: string): Promise<ModuleConfig | undefined> {
moduleDir = ModuleConfigUtil.resolveModuleDir(moduleDir, baseDir);
let defaultConfig = await ModuleConfigUtil.loadModuleYaml(moduleDir);
Expand All @@ -222,8 +248,22 @@ export class ModuleConfigUtil {
return defaultConfig;
}

static async #loadOne(moduleDir: string, configName: string): Promise<ModuleConfig | undefined> {
const yamlConfigPath = path.join(moduleDir, `${configName}.yml`);
let config = await ModuleConfigUtil.#loadYaml(yamlConfigPath);
if (!config) {
const jsonConfigPath = path.join(moduleDir, `${configName}.json`);
config = await ModuleConfigUtil.#loadJson(jsonConfigPath);
}
return config;
}

private static async loadModuleJson(moduleDir: string, env?: string): Promise<ModuleConfig | undefined> {
const moduleJsonPath = ModuleConfigUtil.moduleJsonPath(moduleDir, env);
return await ModuleConfigUtil.#loadJson(moduleJsonPath);
}

static async #loadJson(moduleJsonPath: string): Promise<ModuleConfig | undefined> {
const moduleJsonPathExists = await FSUtil.fileExists(moduleJsonPath);
if (!moduleJsonPathExists) {
return;
Expand All @@ -235,6 +275,10 @@ export class ModuleConfigUtil {

private static async loadModuleYaml(moduleDir: string, env?: string): Promise<ModuleConfig | undefined> {
const moduleYamlPath = ModuleConfigUtil.moduleYamlPath(moduleDir, env);
return await ModuleConfigUtil.#loadYaml(moduleYamlPath);
}

static async #loadYaml(moduleYamlPath: string): Promise<ModuleConfig | undefined> {
const moduleYamlPathExists = await FSUtil.fileExists(moduleYamlPath);
if (!moduleYamlPathExists) {
return;
Expand All @@ -243,6 +287,26 @@ export class ModuleConfigUtil {
return yaml.safeLoad(moduleYamlContent) as ModuleConfigUtil;
}

public static loadSync(moduleDir: string, baseDir?: string): ModuleConfig {
const modulePath = ModuleConfigUtil.resolveModuleDir(moduleDir, baseDir);
assert(ModuleConfigUtil.configNames, 'should setConfigNames before load module config');

const target: ModuleConfig = {};
for (const configName of ModuleConfigUtil.configNames) {
let config = ModuleConfigUtil.#loadOneSync(modulePath, configName);
// both module.yml and module.default.yml are ok for default config
if (configName === 'module.default' && !config) {
config = ModuleConfigUtil.#loadOneSync(modulePath, 'module');
}
if (config) {
extend(true, target, config);
}
}

return target;
}

// @deprecated use loadSync instead
public static loadModuleConfigSync(moduleDir: string, baseDir?: string, env?: string): ModuleConfig | undefined {
moduleDir = ModuleConfigUtil.resolveModuleDir(moduleDir, baseDir);
let defaultConfig = ModuleConfigUtil.loadModuleYamlSync(moduleDir);
Expand All @@ -259,8 +323,22 @@ export class ModuleConfigUtil {
return extend(true, defaultConfig, envConfig);
}

static #loadOneSync(moduleDir: string, configName: string): ModuleConfig | undefined {
const yamlConfigPath = path.join(moduleDir, `${configName}.yml`);
let config = ModuleConfigUtil.#loadYamlSync(yamlConfigPath);
if (!config) {
const jsonConfigPath = path.join(moduleDir, `${configName}.json`);
config = ModuleConfigUtil.#loadJsonSync(jsonConfigPath);
}
return config;
}

private static loadModuleJsonSync(moduleDir: string, env?: string): ModuleConfig | undefined {
const moduleJsonPath = ModuleConfigUtil.moduleJsonPath(moduleDir, env);
return ModuleConfigUtil.#loadJsonSync(moduleJsonPath);
}

static #loadJsonSync(moduleJsonPath: string): ModuleConfig | undefined {
const moduleJsonPathExists = fs.existsSync(moduleJsonPath);
if (!moduleJsonPathExists) {
return;
Expand All @@ -272,6 +350,10 @@ export class ModuleConfigUtil {

private static loadModuleYamlSync(moduleDir: string, env?: string): ModuleConfig | undefined {
const moduleYamlPath = ModuleConfigUtil.moduleYamlPath(moduleDir, env);
return ModuleConfigUtil.#loadYamlSync(moduleYamlPath);
}

static #loadYamlSync(moduleYamlPath: string): ModuleConfig | undefined {
const moduleYamlPathExists = fs.existsSync(moduleYamlPath);
if (!moduleYamlPathExists) {
return;
Expand Down
26 changes: 25 additions & 1 deletion core/common-util/test/ModuleConfig.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import assert from 'node:assert';
import { strict as assert } from 'node:assert';
import path from 'node:path';
import { ModuleConfigUtil } from '../src/ModuleConfig';

Expand Down Expand Up @@ -117,4 +117,28 @@ describe('test/ModuleConfig.test.ts', () => {
}]);
});
});

describe('load/loadSync', () => {
beforeEach(() => {
ModuleConfigUtil.setConfigNames(undefined);
});

it('should work', async () => {
ModuleConfigUtil.setConfigNames([ 'module.default', 'module.dev' ]);
const config = await ModuleConfigUtil.load(path.join(__dirname, './fixtures/modules/dev-module-config'));
const configSync = ModuleConfigUtil.loadSync(path.join(__dirname, './fixtures/modules/dev-module-config'));
assert.deepStrictEqual(config, { mysql: { host: '127.0.0.1', port: 11306 } });
assert.deepStrictEqual(configSync, { mysql: { host: '127.0.0.1', port: 11306 } });
});

it('should throw error without initialization', async () => {
await assert.rejects(async () => {
await ModuleConfigUtil.load(path.join(__dirname, './fixtures/modules/dev-module-config'));
}, /should setConfigNames before load module config/);

assert.throws(() => {
ModuleConfigUtil.loadSync(path.join(__dirname, './fixtures/modules/dev-module-config'));
}, /should setConfigNames before load module config/);
});
});
});
16 changes: 12 additions & 4 deletions plugin/config/app.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import { Application } from 'egg';
import { ModuleConfigUtil, ModuleReference } from '@eggjs/tegg-common-util';
import type { Application, IBoot } from 'egg';
import { ModuleConfigUtil } from '@eggjs/tegg-common-util';
import type { ModuleReference } from '@eggjs/tegg-common-util';
import { ModuleScanner } from './lib/ModuleScanner';

export default class App {
export default class App implements IBoot {
private readonly app: Application;

constructor(app: Application) {
this.app = app;
const configNames = this.app.loader.getTypeFiles('module');
ModuleConfigUtil.setConfigNames(configNames);
}

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

this.app.moduleConfigs = {};

for (const reference of this.app.moduleReferences) {
const absoluteRef: ModuleReference = {
path: ModuleConfigUtil.resolveModuleDir(reference.path, this.app.baseDir),
Expand All @@ -26,8 +30,12 @@ export default class App {
this.app.moduleConfigs[moduleName] = {
name: moduleName,
reference: absoluteRef,
config: ModuleConfigUtil.loadModuleConfigSync(absoluteRef.path, undefined, this.app.config.env) || {},
config: ModuleConfigUtil.loadSync(absoluteRef.path, undefined),
};
}
}

async beforeClose() {
ModuleConfigUtil.setConfigNames(undefined);
}
}

0 comments on commit d034ed9

Please sign in to comment.