独立应用
Nest 应用有多种挂载方式。你可以创建一个 Web 应用、一个微服务,或者仅仅创建一个裸的 Nest 独立应用(不带任何网络监听器)。Nest 独立应用本质上是对 Nest IoC 容器的一层包装,而这个容器中持有所有已实例化的类。借助独立应用对象,我们可以直接从任何已导入模块中拿到任意现有实例的引用。因此,你可以在任何场景下使用 Nest 框架,例如脚本化的 CRON 任务,甚至还可以在其之上构建 CLI。
入门
要创建一个 Nest 独立应用,可以使用如下写法:
async function bootstrap() {
const app = await NestFactory.createApplicationContext(AppModule);
// 在这里编写你的应用逻辑...
}
bootstrap();从静态模块中获取 provider
独立应用对象允许你获取 Nest 应用中注册的任意实例引用。假设 AppModule 导入了 TasksModule,而 TasksModule 中有一个 TasksService provider。这个类提供了一组我们希望在 CRON 任务中调用的方法。
const tasksService = app.get(TasksService);我们使用 get() 方法来访问 TasksService 实例。get() 方法就像一个查询器,它会在所有已注册模块中搜索实例。你可以给它传入任意 provider token。
或者,如果你希望做严格上下文检查,也可以传入 { strict: true } 选项对象。启用该选项后,你需要先导航到具体模块,再从该模块上下文中获取所需实例。
const tasksService = app.select(TasksModule).get(TasksService, { strict: true });下面是独立应用对象上可用于获取实例引用的方法摘要:
get() | 获取应用上下文中可用的 controller 或 provider 实例(包括 guards、filters 等)。 |
select() | 在模块图中导航,选中某个特定模块的上下文,再进一步提取其中的实例(通常与严格模式搭配使用)。 |
提示
在非严格模式下,默认选中的是根模块。如果你要定位其他模块,就需要手动沿着模块图逐步导航。
需要注意的是,独立应用没有任何网络监听器,因此所有与 HTTP 相关的 Nest 特性(例如 middleware、interceptors、pipes、guards 等)在这个上下文中都不可用。
例如,即使你在应用中注册了全局拦截器,然后通过 app.get() 拿到某个 controller 的实例,这个拦截器也不会执行。
从动态模块中获取 provider
当你处理的是动态模块时,应当把与应用中注册时完全相同的动态模块对象传给 app.select()。例如:
export const dynamicConfigModule = ConfigModule.register({ folder: './config' });
@Module({
imports: [dynamicConfigModule],
})
export class AppModule {}之后你就可以这样选中该模块:
const configService = app
.select(dynamicConfigModule)
.get(ConfigService, { strict: true });终止阶段
如果你希望脚本执行结束后关闭 Node 应用(例如执行 CRON 任务的脚本),你必须在 bootstrap 函数末尾显式调用 app.close():
async function bootstrap() {
const app = await NestFactory.createApplicationContext(AppModule);
// 应用逻辑...
await app.close();
}
bootstrap();正如生命周期事件章节中提到的那样,这会触发生命周期钩子。
示例
一个可运行的示例可见这里。