您可以使用glob 包动态查找模块,然后使用NestJs 动态模块功能动态加载它们。
假设您的所有工作文件都存储在名为workers 并扩展名为.worker.ts 的目录中:
@Module({})
export class WorkerModule {
static forRootAsync(): DynamicModule {
return {
module: WorkerModule ,
imports: [WorkerCoreModule.forRootAsync()],
};
}
}
export class WorkerCoreModule {
static async forRootAsync(): Promise<DynamicModule> {
// Feel free to change path if your structure is different
const workersPath = glob.sync('src/**/workers/*.worker.ts');
const workersRelativePathWithoutExt = modelsPath
// Replace src, because you are probably running the code
// from dist folder
.map((path) => path.replace('src/', './../'))
.map((path) => path.replace('.ts', ''));
const workerProviders: Provider<any>[] = [];
const importedModules = await Promise.all(
workersRelativePathWithoutExt.map((path) => import(path)),
);
importedModules.forEach((modules) => {
// Might be different if you are using default export instead
const worker = modules[Object.keys(modules)[0]];
workerProviders.push({
provide: worker.name,
useValue: worker,
});
});
return {
module: WorkerCoreModule,
providers: [...workerProviders],
// You can omit exports if providers are meant to be used
// only in this module
exports: [...workerProviders],
};
}
}
现在假设你有一个简单的工作类,路径为src/anyModule/workers/simple-worker.ts,你可以这样使用它:
class WrokersService {
constructor(@Inject('SimpleWorker') simpleWroker: SimpleWorker) {}
.
.
.
}
如果你想省略 @Inject('SimpleWorker') 并自动注入像 NestJs 服务这样的模块,那么你需要对 WorkerCoreModule 进行这些更改:
workerProviders.push({
provide: worker,
});
但是,为了使其正常工作,您需要确保您的 workers 类使用 @injectable() 装饰。