1. 安装依赖
npm install @brewww/nestjs-plugin-module
2. 定义插件接口
首先,我们需要定义一个插件接口,这个接口定义了插件需要实现的方法。
hello/plugin.interface.ts
export interface HelloServicePlugin {
helloworld(): string;
hello(name: string): string;
}
3. 定义模块和提供者
接下来,我们需要定义一个模块和一个提供者,这里提供者引用了上面的插件实例,并且调用插件实例中的方法。
另外提供者还提供了一个 setHelloServicePlugin() 方法,用来在后面动态设置插件实例。
hello/hello.service.ts
import { Injectable } from '@nestjs/common';
import { HelloServicePlugin } from './plugin.interface';
@Injectable({})
export class HelloService {
private helloServicePlugin: HelloServicePlugin;
public async setHelloServicePlugin(helloServicePlugin: HelloServicePlugin) {
this.helloServicePlugin = helloServicePlugin;
}
helloworld(): string {
return this.helloServicePlugin.helloworld();
}
hello(name: string): string {
return this.helloServicePlugin.hello(name);
}
}
hello.module.ts
import { Module } from '@nestjs/common';
import { HelloService } from './hello.service';
@Module({
providers: [
{
provide: 'HelloService',
useClass: HelloService,
},
],
exports: ['HelloService'],
})
export class HelloModule {}
4. 创建插件
4.1 首先创建 plugins/hello-plugin/src 目录,然后在目录下创建 hello.plugin.ts 文件,实现 HelloServicePlugin 接口,并实现其中的方法。
另外插件实现类还引用了上面模块中的提供者,并在其 load() 方法中调用提供者中的 setHelloServicePlugin() 方法,将插件实例设置到提供者中。
plugins/hello-plugin/src/hello.plugin.ts
import { Inject, Injectable, Logger } from '@nestjs/common';
import { BasePlugin } from '@brewww/nestjs-plugin-module';
import { HelloServicePlugin } from '../../../hello/plugin.interface';
import { HelloService } from '../../../hello/hello.service';
import { pluginModule } from '../package.json';
@Injectable()
export class MyHelloServicePlugin
extends BasePlugin
implements HelloServicePlugin
{
private readonly logger = new Logger(MyHelloServicePlugin.name);
@Inject('HelloService')
private helloService: HelloService;
constructor() {
super(pluginModule);
}
public helloworld(): string {
return 'Hello World';
}
public hello(name: string): string {
return 'Hello ' + name;
}
async load(): Promise<void> {
this.logger.debug(`MyHelloServicePlugin.load ...`);
this.helloService.setHelloServicePlugin(this);
return Promise.resolve();
}
}
- 这里注意一下,我们需要修改tsconfig.json,并添加以下配置项
"resolveJsonModule": true
4.2 在 plugins/hello-plugin/src 目录下创建 index.ts 文件,在其中引入 MyHelloServicePlugin 类,并导出它。
plugins/hello-plugin/src/index.ts
import { MyHelloServicePlugin } from './hello.plugin';
export { MyHelloServicePlugin };
4.3 在 plugins/hello-plugin 目录下创建 package.json 文件,在其中定义插件的名称和显示名称。
plugins/hello-plugin/package.json
{
"pluginModule": {
"name": "my-hello-plugin",
"displayName": "My Hello Plugin"
}
}
5. 配置插件模块
app.module.ts
import { Module, forwardRef } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { PluginModule } from '@brewww/nestjs-plugin-module';
import { HelloModule } from './hello/hello.module';
import * as path from 'path';
@Module({
imports: [
PluginModule.registerAsync({
imports: [forwardRef(() => HelloModule)],
directories: [path.resolve(__dirname, './plugins')],
}),
HelloModule,
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
- 这里使用PluginModule.registerAsync()方法注册插件模块,并传入HelloModule模块,这样HelloModule中的提供者就可以被插件模块中的插件使用。
6. 测试插件
作为测试,我们在controller中注入HelloService,并调用其中的方法,看是否能够正确输出结果。
app.controller.ts
import { Controller, Get, Inject } from '@nestjs/common';
import { AppService } from './app.service';
import { HelloService } from './hello/hello.service';
@Controller()
export class AppController {
constructor(
private readonly appService: AppService,
@Inject('HelloService')
private readonly helloService: HelloService,
) {}
@Get()
async getHello() {
console.log(this.helloService.helloworld());
console.log(this.helloService.hello('kongxx'));
return this.appService.getHello();
}
}