Nest 模块
Nest 模块
模块 (Modules) 是应用程序的基本构建块,它将一组相关的功能组织在一起。
创建模块
使用如下命令可以快速创建一个模块。
nest generate module <MODULE_NAME><MODULE_NAME> 可以是文件路径,例如 user/auth。
这里我们创建一个 todo 模块。
nest generate module features/todo此时会在 src/features/todo 下生成一个 todo.module.ts 文件。
其内容如下。
import { Module } from '@nestjs/common'
@Module({})
export class TodoModule {}同时,在 app.module.ts 文件中自动引入了 TodoModule。
import { Module } from '@nestjs/common'
import { AppController } from './app.controller'
import { AppService } from './app.service'
import { TodoModule } from './features/todo/todo.module'
@Module({
imports: [TodoModule],
controllers: [AppController],
providers: [AppService]
})
export class AppModule {}参数介绍
创建完的模块文件中,默认会生成一个空的 @Module() 装饰器,它接受一个对象作为参数,该对象包含以下属性。
imports:导入列表,导入该模块需要依赖的其他模块的提供者 (Providers)。controllers:控制器列表,即该模块包含的控制器 (Controllers)。providers:提供者列表,注册模块中使用到的提供者 (Providers)。exports:导出列表,即该模块需要共享给其他模块的提供者 (Providers)。
功能模块
功能模块是包含一组相关功能的模块,大多数模块都是功能模块。
我们将控制器添加到 TodoModule 中。
nest generate controller features/todo此时会在 src/features/todo 下生成一个 todo.controller.ts 文件和 todo.controller.spec.ts 文件。
并且,在 todo.module.ts 文件中自动引入了 TodoController。
import { Module } from '@nestjs/common'
import { TodoController } from './todo.controller'
@Module({
controllers: [TodoController]
})
export class TodoModule {}这里我们把服务 (Services) 也添加到 TodoModule 中。
nest generate service features/todo此时会在 src/features/todo 下生成一个 todo.service.ts 文件和 todo.service.spec.ts 文件。
并且,在 todo.module.ts 文件中自动引入了 TodoService。
import { Module } from '@nestjs/common'
import { TodoController } from './todo.controller'
import { TodoService } from './todo.service'
@Module({
controllers: [TodoController],
providers: [TodoService]
})
export class TodoModule {}此时我们修改 todo.service.ts 中的内容。
import { Injectable } from '@nestjs/common'
@Injectable()
export class TodoService {
private todos = [
{
id: 1,
title: 'First Todo',
description: 'This is the first todo'
}
]
getTodos() {
return this.todos
}
}再修改 todo.controller.ts 中的内容,将 TodoService 注入到 TodoController 中。
import { Controller, Get } from '@nestjs/common'
import { TodoService } from './todo.service'
@Controller('todos')
export class TodoController {
constructor(private readonly todoService: TodoService) {}
@Get()
getAll() {
return this.todoService.getTodos()
}
}此时我们就创建了一个功能模块,它包含一个控制器和一个服务。访问 http://localhost:3000/todos 可以看到返回的数据。
共享模块
在 Nest 中,默认情况下,模块是单例的,也就是说可以在多个模块间共享同一个实例。
这里我们把 TodoService 从 TodoModule 中导出。
import { Module } from '@nestjs/common'
import { TodoController } from './todo.controller'
import { TodoService } from './todo.service'
@Module({
controllers: [TodoController],
providers: [TodoService],
exports: [TodoService]
})
export class TodoModule {}然后我们建立一个新的模块和控制器。
nest generate module features/copy-todonest generate controller features/copy-todo然后我们调整一下 todo.service.ts 文件中的内容,增加了一个 createTodo 方法。
import { Injectable } from '@nestjs/common'
@Injectable()
export class TodoService {
private todos = [
{
id: 1,
title: 'First Todo',
description: 'This is the first todo'
}
]
getTodos() {
return this.todos
}
createTodo(item) {
this.todos.push(item)
}
}然后在 CopyTodoModule 中导入 TodoModule。
import { Module } from '@nestjs/common'
import { CopyTodoController } from './copy-todo.controller'
import { TodoModule } from '../todo/todo.module'
@Module({
controllers: [CopyTodoController],
imports: [TodoModule]
})
export class CopyTodoModule {}然后在 CopyTodoController 中注入 TodoService,并调用 createTodo 方法。
import { Body, Controller, Post } from '@nestjs/common'
import { TodoService } from '../todo/todo.service'
@Controller('copy-todos')
export class CopyTodoController {
constructor(private readonly todoService: TodoService) {}
@Post()
create(@Body() body) {
this.todoService.createTodo(body)
return body
}
}当我们向 http://localhost:3000/copy-todos 发送一个 POST 请求时,可以看到返回的数据,并且我们再访问 http://localhost:3000/todos,可以看到 todos 数组中多了一个元素。
这里我们可以得出一个结论,像服务 (Services) 这样的提供者 (Providers) 会在模块 (Modules) 中建立一个实例,当其他模块 (Modules) 需要使用这个实例时,就可以通过导出的方式与其他模块 (Modules) 共享。

全局模块
当有模块需要与多数模块共享时,需要在各模块中导入它,这样会显得很麻烦。此时我们可以将模块标记为全局模块,这样其他模块不需要导入它就可以使用了。
要将模块标记为全局模块,只需给模块添加 @Global() 装饰器即可。
import { Global, Module } from '@nestjs/common'
import { TodoController } from './todo.controller'
import { TodoService } from './todo.service'
@Global()
@Module({
controllers: [TodoController],
providers: [TodoService],
exports: [TodoService]
})
export class TodoModule {}这里我们给 TodoModule 添加了 @Global() 装饰器,这样我们就可以在 CopyTodoModule 中使用 TodoService 了,而不需要导入 TodoModule。
注意:非必要情况下,不建议使用全局模块。
常用模块
模块可以不包含任何控制器 (Controllers) 与提供者 (Providers),只把导入的模块再导出,这样的好处是可以把多个常用的模块集中在一起,方便在其他模块中使用。
import { Module } from '@nestjs/common'
@Module({
imports: [AModule, BModule],
exports: [AModule, BModule]
})
export class CommonModule {}