模块Module

每个Nest应用程序至少有一个模块,即根模块,根模块是Nest开始安排应用进程树的地方

当应用程序很小时,根模块可能是应用程序中唯一的模块

大型程序在大多数情况下将拥有多个模块,每个模块都有一组紧密相关的功能

用法

基本用法

使用nest g res [模块名]创建CURD模板时,Nestjs会自动在根模块处引入新模块

1
2
3
4
5
6
7
8
9
10
11
12
13
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { UserModule } from './user/user.module';
import { ListModule } from './list/list.module';

@Module({
// 引入了模块
imports: [UserModule, ListModule],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}

共享模块

user不是一个共享模块,所以user Service的一切只能在user模块内部使用,在其他模块使用会报错:

可以在user.module.ts中导出Service:

1
2
3
4
5
6
7
8
9
10
11
import { Module } from '@nestjs/common';
import { UserService } from './user.service';
import { UserController } from './user.controller';

@Module({
controllers: [UserController],
providers: [UserService],
// 导出UserService
exports: [UserService],
})
export class UserModule {}

这下就不会报错了:

全局模块

给模块添加@Global使其被注册为全局模块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import { Global, Module } from '@nestjs/common';

@Global()
@Module({
providers: [
{
provide: 'Config',
useValue: { baseUrl: '/api' },
},
],
// 即使已注册成全局模块仍然要做导出
exports: [
{
provide: 'Config',
useValue: { baseUrl: '/api' },
},
],
})
export class ConfigModule {}

在根模块里引入全局模块ConfigModule:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { UserModule } from './user/user.module';
import { ListModule } from './list/list.module';
import { ConfigModule } from './config/config.module';

@Module({
// 引入了模块
imports: [UserModule, ListModule, ConfigModule],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}

在list.controller.ts中使用全局模块,不需要使用import(可以全局使用):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import { Controller, Inject } from '@nestjs/common';
import { ListService } from './list.service';
import { CreateListDto } from './dto/create-list.dto';
import { UpdateListDto } from './dto/update-list.dto';

@Controller('list')
export class ListController {
constructor(@Inject('Config') private readonly base: any) {}

@Get()
findAll() {
return this.base;
}
}

动态模块

使用动态模块主要是为给模块传递参数,可以给该模块添加一个静态方法,用来接受参数

在config.module.ts中,forRoot就是能接收参数的静态方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import { DynamicModule, Global, Module } from '@nestjs/common';

interface Options {
path: string;
}

@Global()
@Module({})
export class ConfigModule {
// 使用静态函数forRoot
static forRoot(options: Options): DynamicModule {
return {
module: ConfigModule,
providers: [
{
provide: 'Config',
useValue: { baseUrl: '/api' + options.path },
},
],
// 即使已注册成全局模块仍然要做导出
exports: [
{
provide: 'Config',
useValue: { baseUrl: '/api' },
},
],
};
}
}

在app.module.ts中,注册ConfigModule中的该静态方法,并传参:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { UserModule } from './user/user.module';
import { ListModule } from './list/list.module';
import { ConfigModule } from './config/config.module';

@Module({
// 引入时把静态方法引进来,还能传个参
imports: [
UserModule,
ListModule,
ConfigModule.forRoot({
path: './root',
}),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}