模块是具有 @Module()装饰器的类。 @Module()装饰器提供了元数据,Nest 用它来组织应用程序结构。
每个Nest应用程序至少有一个模块,即根模块。根模块是Nest开始安排应用程序树的地方。事实上,根模块可能是应用程序中唯一的模块,特别是当应用程序很小时,但是对于大型程序来说这是没有意义的。在大多数情况下,我们将拥有多个模块,每个模块都有一组紧密相关的功能。
在我们创建好的项目中,其中app.module.ts就是我们的根模块:
@Module({
imports: [],
controllers: [AppController],
providers: [AppService],
exports: []
})
@module() 装饰器接受一个描述模块属性的对象:
- imports
导入模块的列表,这些模块导出了此模块中所需提供者
- controllers
必须创建的一组控制器
- providers
由Nest注入器实例化的提供者,并且可以至少在整个模块中共享
- exports
由本模块提供并应在其他模块中可用的提供者的子集。
Nest是模块化开发的模式,那么对于我们来说,将控制器以及提供者等放在同一个模块内是十分合理的做法。
在前面几篇中,我们创建了user的控制器,服务类,这里我们创建模块:
PS D:\ms\src> nest g module user
CREATE /user/user.module.ts (81 bytes)
UPDATE /app.module.ts (455 bytes)
此时在user目录下会自动生成user.module.ts文件:
import { Module } from '@nestjs/common';
@Module({})
export class UserModule {}
同时,在app.module.ts中会自动导入我们创建的模块,这一步很重要的:
imports: [UserModule],
接下来我们需要在UserModule模块中,注册控制器和提供者:
import { Module } from '@nestjs/common';
import { UserController } from './user.controller';
import { UserService } from './user.service';
@Module({
controllers: [UserController],
providers: [UserService]
})
export class UserModule {
}
在app.module.ts中我们就可以不用注册UserController和UserService了:
@Module({
imports: [UserModule],
controllers: [AppController],
providers: [AppService],
})
共享模块
在Nest中,默认情况下,模块是单例,因此我们可以轻松地在多个模块之间共享同一个提供者实例。实际上每个模块都是一个共享模块,一旦创建就能被任意模块重复使用,比如我们的UserService还希望在其他地方使用,那么我们可以将其添加至exports数据中进行导出:
@Module({
exports: [UserService],
})
此时每个导入UserModule的模块都可以访问UserService,并且它们将共享相同的UserService 实例。
比如我们在app.controller.ts中使用UserService:
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';
import { UserService } from './user/user.service';
@Controller()
export class AppController {
constructor(private readonly appService: AppService, private readonly userService: UserService) { }
@Get()
getHello(): string {
this.userService.create({ "name": "nest", "age": 10, "gender": 0 });
return JSON.stringify(this.userService.getAllUsers());
}
}
我们看看两者的数据是否一致: