Nest入門教程 - 模塊

Nest入門教程 - 模塊

 

模塊

模塊是具有 @Module() 裝飾器的類。 @Module() 裝飾器提供了元數據,Nest 用它來組織應用程序結構。

圖1

每個 Nest 應用程序至少有一個模塊,即根模塊。根模塊是 Nest 開始安排應用程序樹的地方。事實上,根模塊可能是應用程序中唯一的模塊,特別是當應用程序很小時,但是對於大型程序來說這是沒有意義的。在大多數情況下,您將擁有多個模塊,每個模塊都有一組緊密相關的功能

@module() 裝飾器接受一個描述模塊屬性的對象:

   
providers 由 Nest 注入器實例化的提供者,並且可以至少在整個模塊中共享
controllers 必須創建的一組控制器
imports 導入模塊的列表,這些模塊導出了此模塊中所需提供者
exports 由本模塊提供並應在其他模塊中可用的提供者的子集。

默認情況下, 模塊封裝提供者。這意味着如果提供者即不是當前模塊的一部分, 也不是從另外模塊(已導入)導出的,那麼它就是無法注入的。

 

功能模塊

CatsController 和 CatsService 屬於同一個應用程序域。 應該考慮將它們移動到一個功能模塊下,即 CatsModule

cats/cats.module.ts

import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
export class CatsModule {}Copy to clipboardErrorCopied

要使用 CLI 創建模塊,只需執行 $ nest g module cats 命令。

我已經創建了 cats.module.ts 文件,並把與這個模塊相關的所有東西都移到了 cats 目錄下。我們需要做的最後一件事是將這個模塊導入根模塊 (ApplicationModule)

app.module.ts

import { Module } from '@nestjs/common';
import { CatsModule } from './cats/cats.module';

@Module({
  imports: [CatsModule],
})
export class ApplicationModule {}Copy to clipboardErrorCopied

現在 Nest 知道除了 ApplicationModule 之外,註冊 CatsModule 也是非常重要的。 這就是我們現在的目錄結構:

src
├──cats
│    ├──dto
│    │   └──create-cat.dto.ts
│    ├──interfaces
│    │     └──cat.interface.ts
│    ├─cats.service.ts
│    ├─cats.controller.ts
│    └──cats.module.ts
├──app.module.ts
└──main.tsCopy to clipboardErrorCopied

 

共享模塊

在 Nest 中,默認情況下,模塊是單例,因此您可以輕鬆地在多個模塊之間共享同一個提供者實例。

圖1

實際上,每個模塊都是一個共享模塊。一旦創建就能被任意模塊重複使用。假設我們將在幾個模塊之間共享 CatsService 實例。 我們需要把 CatsService 放到 exports 數組中,如下所示:

cats.module.ts

import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
  exports: [CatsService]
})
export class CatsModule {}Copy to clipboardErrorCopied

現在,每個導入 CatsModule 的模塊都可以訪問 CatsService ,並且它們將共享相同的 CatsService 實例。

 

模塊導出

模塊可以導出他們的內部提供者。 而且,他們可以再導出自己導入的模塊。

@Module({
  imports: [CommonModule],
  exports: [CommonModule],
})
export class CoreModule {}Copy to clipboardErrorCopied

 

依賴注入

提供者也可以注入到模塊(類)中(例如,用於配置目的):

cats.module.ts

import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
export class CatsModule {
  constructor(private readonly catsService: CatsService) {}
}Copy to clipboardErrorCopied

但是,由於循環依賴性,模塊類不能注入到提供者中。

 

全局模塊

如果你不得不在任何地方導入相同的模塊,那可能很煩人。在 Angular 中,提供者是在全局範圍內註冊的。一旦定義,他們到處可用。另一方面,Nest 將提供者封裝在模塊範圍內。您無法在其他地方使用模塊的提供者而不導入他們。但是有時候,你可能只想提供一組隨時可用的東西 - 例如:helper,數據庫連接等等。這就是爲什麼你能夠使模塊成爲全局模塊。

import { Module, Global } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Global()
@Module({
  controllers: [CatsController],
  providers: [CatsService],
  exports: [CatsService],
})
export class CatsModule {}Copy to clipboardErrorCopied

@Global 裝飾器使模塊成爲全局作用域。 全局模塊應該只註冊一次,最好由根或核心模塊註冊。 在上面的例子中,CatsService 組件將無處不在,而想要使用 CatsService 的模塊則不需要在 imports 數組中導入 CatsModule

使一切全局化並不是一個好的解決方案。 全局模塊可用於減少必要模板文件的數量。 imports 數組仍然是使模塊 API 透明的最佳方式。

 

動態模塊

Nest 模塊系統帶有一個稱爲動態模塊的功能。 它使您能夠毫不費力地創建可定製的模塊。 讓我們來看看 DatabaseModule

import { Module, DynamicModule } from '@nestjs/common';
import { createDatabaseProviders } from './database.providers';
import { Connection } from './connection.provider';

@Module({
  providers: [Connection],
})
export class DatabaseModule {
  static forRoot(entities = [], options?): DynamicModule {
    const providers = createDatabaseProviders(options, entities);
    return {
      module: DatabaseModule,
      providers: providers,
      exports: providers,
    };
  }
}Copy to clipboardErrorCopied

forRoot() 可以同步或異步(Promise)返回動態模塊。

此模塊默認定義了 Connection 提供者,但另外 - 根據傳遞的 options 和 entities - 創建一個提供者集合,例如存儲庫。實際上,動態模塊擴展了模塊元數據。當您需要動態註冊組件時,這個實質特性非常有用。然後你可以通過以下方式導入 DatabaseModule

import { Module } from '@nestjs/common';
import { DatabaseModule } from './database/database.module';
import { User } from './users/entities/user.entity';

@Module({
  imports: [DatabaseModule.forRoot([User])],
})
export class ApplicationModule {}Copy to clipboardErrorCopied

爲了導出動態模塊,可以省略函數調用部分:

import { Module } from '@nestjs/common';
import { DatabaseModule } from './database/database.module';
import { User } from './users/entities/user.entity';

@Module({
  imports: [DatabaseModule.forRoot([User])],
  exports: [DatabaseModule],
})
export class ApplicationModule {}Copy to clipboardErrorCopied

 

譯者署名

用戶名 頭像 職能 簽名
@zuohuadong 翻譯 專注於 caddy 和 nest,@zuohuadong at Github
@Armor 翻譯 專注於 Java 和 Nest,@Armor
@Drixn 翻譯 專注於 nginx 和 C++,@Drixn
@tangkai 翻譯 專注於 React,@tangkai
@havef 校正 數據分析、機器學習、TS/JS技術棧 @havef
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章