@jmodule/client
Version:
JModule运行时
88 lines (81 loc) • 3.38 kB
text/typescript
import { ModuleDebug } from '../debug';
import { JModule } from '../module';
import { ModuleMetadata, ModuleStatus } from '../config';
import { eventToPromise } from './eventToPromise';
import type { JModuleManager } from '../globalManager';
async function initModule(this: typeof JModuleManager, module: JModule, pkg: ModuleMetadata): Promise<JModule> {
const { key } = module;
const runHook = (module.constructor as any).runHook;
ModuleDebug.print({ key, message: '开始执行初始化函数', instance: pkg });
try {
// module init
if (typeof pkg.init === 'function') {
ModuleDebug.printContinue('执行 init 函数');
await pkg.init(module);
}
await runHook('afterInit', module, pkg);
// imports
(pkg.imports || []).forEach((moduleKey: string) => {
ModuleDebug.printContinue('加载依赖模块');
this.waitModuleComplete(moduleKey).then((item: JModule) => item.load());
});
await runHook('afterImports', module, pkg);
// exports
this.cacheModuleExport(key, pkg.exports);
await runHook('afterExports', module, pkg);
return module;
} catch (e) {
console.error(e);
ModuleDebug.print({
type: 'error',
key,
message: (e as Error).message || '未找到模块注册信息, 或模块参数错误',
instance: e,
});
throw e;
}
}
function define(moduleKey: string, metadata: ModuleMetadata & Record<string, any>): Promise<JModule>;
function define(metadata: ModuleMetadata & Record<string, any>): Promise<JModule>;
function define(this: typeof JModuleManager, moduleKey: any, metadata?: any): Promise<JModule> {
let localKey: string;
let localMetadata: ModuleMetadata;
/* eslint-disable */
if (!metadata) {
localKey = moduleKey.key;
localMetadata = moduleKey;
} else {
localKey = moduleKey;
localMetadata = metadata;
}
const moduleDefer: Promise<JModule> = this.jmodule(localKey)
? Promise.resolve(this.jmodule(localKey) as JModule)
: eventToPromise(`module.${moduleKey}.${ModuleStatus.init}`);
// 在定义之前执行将出现异常
return moduleDefer.then((module: JModule) => {
module.bootstrap = () => {
module.status = ModuleStatus.booting;
const targetConstructor = module.constructor as any;
let defer = targetConstructor.runHook('beforeDefine', module, localMetadata)
.then(() => initModule.bind(this)(module, localMetadata))
.then(() => {
targetConstructor.runHook('afterDefine', module, localMetadata)
module.status = ModuleStatus.done; // 初始化完成
return module;
})
.catch((err: Error) => {
module.status = ModuleStatus.bootFailure;
throw err;
});
module.bootstrap = () => defer; // 重写bootstrap, 避免重复执行
return defer;
}
// 模块状态:已定义
module.status = ModuleStatus.defined;
if (module.autoBootstrap) {
return module.bootstrap();
}
return module;
});
}
export const defineModule = define;