Skip to content

Commit

Permalink
fix(loader): lifecycle loader support named export (#183)
Browse files Browse the repository at this point in the history
  • Loading branch information
noahziheng authored Aug 26, 2022
1 parent fed9fba commit a08f19d
Show file tree
Hide file tree
Showing 12 changed files with 70 additions and 33 deletions.
7 changes: 6 additions & 1 deletion src/lifecycle/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Constructable, Container } from '@artus/injection';
import { Application } from '../types';
import { Application, ApplicationLifecycle } from '../types';
import {
HOOK_NAME_META_PREFIX,
} from '../constant';
Expand All @@ -22,6 +22,7 @@ export class LifecycleManager {
hookFnMap: Map<string, HookFunction[]> = new Map();
private app: Application;
private container: Container;
private hookUnitSet: Set<Constructable<ApplicationLifecycle>> = new Set();

constructor(app: Application, container: Container) {
this.app = app;
Expand All @@ -48,6 +49,10 @@ export class LifecycleManager {
}

registerHookUnit(extClazz: Constructable<any>) {
if (this.hookUnitSet.has(extClazz)) {
return;
}
this.hookUnitSet.add(extClazz);
const fnMetaKeys = Reflect.getMetadataKeys(extClazz);
const extClazzInstance = this.container.get(extClazz);
for (const fnMetaKey of fnMetaKeys) {
Expand Down
2 changes: 1 addition & 1 deletion src/loader/factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ export class LoaderFactory {
loadItem(item: ManifestItem): Promise<any> {
const loaderName = item.loader || DEFAULT_LOADER;
const loader = this.getLoader(loaderName);
loader.state = item._loaderState;
loader.state = item.loaderState;
return loader.load(item);
}

Expand Down
22 changes: 17 additions & 5 deletions src/loader/impl/lifecycle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,24 @@ class LifecycleLoader implements Loader {
this.container = container;
}

get lifecycleManager(): LifecycleManager {
return this.container.get(ArtusInjectEnum.LifecycleManager);
}

async load(item: ManifestItem) {
const extClazz: Constructable<ApplicationLifecycle> = await compatibleRequire(item.path);
const lifecycleManager: LifecycleManager = this.container.get(ArtusInjectEnum.LifecycleManager);
this.container.set({ type: extClazz });
lifecycleManager.registerHookUnit(extClazz);
return extClazz;
const origin: Constructable<ApplicationLifecycle>[] = await compatibleRequire(item.path, true);
item.loaderState = Object.assign({ exportNames: ['default'] }, item.loaderState);
const { loaderState: state } = item as { loaderState: { exportNames: string[] } };

const lifecycleClazzList = [];

for (const name of state.exportNames) {
const clazz = origin[name];
this.container.set({ type: clazz });
this.lifecycleManager.registerHookUnit(clazz);
}

return lifecycleClazzList;
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/loader/impl/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ class ModuleLoader implements Loader {

async load(item: ManifestItem): Promise<Constructable[]> {
const origin = await compatibleRequire(item.path, true);
item._loaderState = Object.assign({ exportNames: ['default'] }, item._loaderState);
const { _loaderState: state } = item as { _loaderState: { exportNames: string[] } };
item.loaderState = Object.assign({ exportNames: ['default'] }, item.loaderState);
const { loaderState: state } = item as { loaderState: { exportNames: string[] } };

const modules: Constructable[] = [];

Expand Down
2 changes: 1 addition & 1 deletion src/loader/impl/plugin_config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class PluginConfigLoader extends ConfigLoader implements Loader {
`Plugin ${pluginName} config can't have both package and path at ${item.path}`,
);
}
const loaderState = item._loaderState as { baseDir: string };
const loaderState = item.loaderState as { baseDir: string };
pluginConfigItem.path = ArtusPlugin.getPath(pluginConfigItem.package, [loaderState?.baseDir]);
delete pluginConfigItem.package;
configObj[pluginName] = pluginConfigItem;
Expand Down
2 changes: 1 addition & 1 deletion src/loader/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ interface ManifestItem<LoaderState = unknown> extends Record<string, any> {
loader?: string;
source?: string;
unitName?: string;
_loaderState?: LoaderState;
loaderState?: LoaderState;
}

interface LoaderFindOptions {
Expand Down
2 changes: 1 addition & 1 deletion src/scanner/scan.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ export class Scanner {
filename,
loader,
source: 'config',
_loaderState: {
loaderState: {
baseDir,
},
};
Expand Down
2 changes: 1 addition & 1 deletion src/scanner/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export class ScanUtils {
source,
};
if (loaderState) {
item._loaderState = loaderState;
item.loaderState = loaderState;
}
unitName && (item.unitName = unitName);
const itemList = options.itemMap.get(item.loader ?? DEFAULT_LOADER);
Expand Down
1 change: 1 addition & 0 deletions test/fixtures/app_with_lifecycle/bootstrap_duplicated.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './bootstrap_ready';
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import LifecycleList from './lifecyclelist';
export const TEST_LIFE_CYCLE_LIST = 'TEST_LIFE_CYCLE_LIST';

@LifecycleHookUnit()
export default class AppLifecycle implements ApplicationLifecycle {
export default class AppLoadLifecycle implements ApplicationLifecycle {
@Inject(ArtusInjectEnum.Application)
app: ArtusApplication;

Expand Down Expand Up @@ -36,22 +36,4 @@ export default class AppLifecycle implements ApplicationLifecycle {
await new Promise(resolve => setTimeout(resolve, 100));
this.lifecycleList.add('app_didLoad');
}

@LifecycleHook('willReady')
async willReady() {
await new Promise(resolve => setTimeout(resolve, 100));
this.lifecycleList.add('app_willReady');
}

@LifecycleHook('didReady')
async didReady() {
await new Promise(resolve => setTimeout(resolve, 100));
this.lifecycleList.add('app_didReady');
}

@LifecycleHook()
async beforeClose() {
await new Promise(resolve => setTimeout(resolve, 100));
this.lifecycleList.add('app_beforeClose');
}
}
37 changes: 37 additions & 0 deletions test/fixtures/app_with_lifecycle/bootstrap_ready.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import {
ArtusApplication,
ApplicationLifecycle, LifecycleHookUnit, LifecycleHook, ArtusInjectEnum,
} from '../../../src/index';

import { Container, Inject } from '@artus/injection';
import LifecycleList from './lifecyclelist';

@LifecycleHookUnit()
export class AppReadyLifecycle implements ApplicationLifecycle {
@Inject(ArtusInjectEnum.Application)
app: ArtusApplication;

@Inject()
container: Container;

@Inject()
lifecycleList: LifecycleList;

@LifecycleHook('willReady')
async willReady() {
await new Promise(resolve => setTimeout(resolve, 100));
this.lifecycleList.add('app_willReady');
}

@LifecycleHook('didReady')
async didReady() {
await new Promise(resolve => setTimeout(resolve, 100));
this.lifecycleList.add('app_didReady');
}

@LifecycleHook()
async beforeClose() {
await new Promise(resolve => setTimeout(resolve, 100));
this.lifecycleList.add('app_beforeClose');
}
}
2 changes: 1 addition & 1 deletion test/fixtures/module_with_custom_loader/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export default ({
extname: '.ts',
filename: 'test_clazz.ts',
loader: 'test-custom-loader',
_loaderState: {
loaderState: {
hello: 'loaderState',
},
},
Expand Down

0 comments on commit a08f19d

Please sign in to comment.