Modules

Modules

모듈은 @Module() 데코레이터로 주석이 달린 클래스입니다. @Module() 데코레이터는 Nest가 응용 프로그램 구조를 구성하는 데 사용하는 메타 데이터를 제공합니다.

각 응용 프로그램에는 하나 이상의 모듈인 루트 모듈이 있습니다. 루트 모듈은 Nest가 응용 프로그램 그래프를 빌드하기 위해 사용하는 시작점입니다. - Nest는 모듈과 공급자 관계 및 종속성을 해결하는 데 사용하는 내부 데이터 구조입니다. 아주 작은 응용 프로그램에는 이론적으로 루트 모듈만 있을 수 있지만 일반적인 경우는 아닙니다. 구성 요소를 효과적으로 구성하려면 모듈을 강력히 권장합니다. 따라서 대부분의 애플리케이션에서 결과 아키텍처는 여러 모듈을 사용하며 각 모듈은 밀접하게 관련된 기능 세트를 캡슐화합니다.

@Module() 데코레이터는 속성이 모듈을 설명하는 단일 객체를 취합니다.

providers

Nest 인젝터에 의해 인스턴스화되고 적어도이 모듈에서 공유 될 수있는 공급자

controllers

인스턴스화해야하는이 모듈에 정의 된 컨트롤러 세트

imports

이 모듈에 필요한 제공자를 내보내는 가져온 모듈 목록

exports

이 모듈에서 제공하며 이 모듈을 가져 오는 다른 모듈에서 사용할 수있는 공급자의 하위 집합

이 모듈은 기본적으로 제공자를 캡슐화합니다. 이는 현재 모듈의 일부가 아니거나 가져온 모듈에서 내 보내지 않은 공급자를 주입 할 수 없음을 의미합니다. 따라서 모듈에서 내 보낸 공급자를 모듈의 공용 인터페이스 또는 API로 간주 할 수 있습니다.

Feature modules

CatsControllerCatsService는 동일한 애플리케이션 도메인에 속합니다. 밀접하게 관련되어 있으므로 기능 모듈로 이동하는 것이 좋습니다. 기능 모듈은 단순히 특정 기능과 관련된 코드를 구성하여 코드를 체계적으로 유지하고 명확한 경계를 설정합니다. 이를 통해 특히 응용 프로그램 및 / 또는 팀의 규모가 커짐에 따라 SOLID 원칙으로 복잡성을 관리하고 개발할 수 있습니다.

이를 설명하기 위해 CatsModule을 만듭니다.

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

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

info 힌트 CLI를 사용하여 모듈을 만들려면 간단히$ nest g module cats 명령을 실행하십시오.

위에서 우리는 cats.module.ts 파일에서 CatsModule을 정의하고 이 모듈과 관련된 모든 것을 cats 디렉토리로 옮겼습니다. 마지막으로 해야 할 일은 이 모듈을 루트 모듈 ( app.module.ts 파일에 정의 된 AppModule)로 가져 오는 것입니다.

@@filename(app.module)
import { Module } from '@nestjs/common';
import { CatsModule } from './cats/cats.module';

@Module({
  imports: [CatsModule],
})
export class AppModule {}

디렉토리 구조는 다음과 같습니다.

  • src

    • cats

      • dto

        • create-cat.dto.ts

      • interfaces

        • cat.interface.ts

      • cats.service.ts

      • cats.controller.ts

      • cats.module.ts

    • app.module.ts

    • main.ts

Shared modules

Nest에서 모듈은 기본적으로 단일이므로 여러 모듈간에 동일한 공급자 인스턴스를 손쉽게 공유 할 수 있습니다.

모든 모듈은 자동으로 공유 모듈입니다. 일단 생성되면 모든 모듈에서 재사용할 수 있습니다. 다른 모듈들 사이에 CatsService의 인스턴스를 공유하고 싶다고 상상해 보자. 이를 위해서는 먼저 아래와 같이 CatsService 공급자를 모듈의 exports 배열에 추가하여 CatsService내 보내야합니다.

@@filename(cats.module)
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 {}

이제 CatsModule을 가져 오는 모든 모듈은 CatsService에 액세스할 수 있으며 이를 가져 오는 다른 모든 모듈과 동일한 인스턴스를 공유합니다.

Module re-exporting

위에서 볼 수 있듯이 모듈은 내부 공급자를 내보낼 수 있습니다. 또한 가져온 모듈을 다시 내보낼 수 있습니다. 아래 예에서 CommonModuleCoreModule 에서 내보내고 는 이 모듈을 가져 오는 다른 모듈에서도 사용할 수 있습니다.

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

Dependency injection

모듈 클래스는 (예: 구성 목적으로) 공급자를 주입 할 수 있습니다 :

@@filename(cats.module)
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) {}
}
@@switch
import { Module, Dependencies } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
@Dependencies(CatsService)
export class CatsModule {
  constructor(catsService) {
    this.catsService = catsService;
  }
}

그러나 circular dependency로 인해 모듈 클래스 자체를 공급자로 삽입할 수 없습니다.

Global modules

모든 곳에서 동일한 모듈 세트를 가져와야하는 경우 지루할 수 있습니다. Nest와 달리 Angular 공급자는 글로벌 범위에 등록되어 있습니다. 일단 정의되면 어디서나 사용할 수 있습니다. 그러나 Nest는 모듈 범위 내에서 공급자를 캡슐화합니다. 캡슐화 모듈을 먼저 가져 오지 않으면 모듈의 공급자를 다른 곳에서 사용할 수 없습니다.

즉시 사용할 수있는 공급자 (예: 헬퍼, 데이터베이스 연결 등)를 제공하려면 @Global()데코레이터로 global 모듈을 만드십시오. .

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 {}

@Global() 데코레이터는 모듈을 전역 범위로 만듭니다. 전역 모듈은 일반적으로 루트 또는 코어 모듈로 한 번만 등록해야 합니다. 위의 예에서 CatsService 공급자는 어디에나 있을 수 있으며, 서비스를 주입하고자 하는 모듈은 CatsModule을 imports 배열로 가져올 필요가 없습니다.

info 힌트 모든 것을 글로발하게 만드는 것은 좋은 디자인 결정이 아닙니다. 필요한 상용구의 양을 줄이기 위해 글로벌 모듈을 사용할 수 있습니다. imports 배열은 일반적으로 소비자가 모듈의 API를 사용할 수 있도록하는 기본 방법입니다.

Dynamic modules

Nest 모듈 시스템에는 동적 모듈이라는 기능이 있습니다. 이 기능을 사용하면 사용자 지정 가능한 모듈을 쉽게 만들 수 있습니다. 다음은 이러한 동적 모듈인 DatabaseModule의 예입니다.

@@filename()
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,
    };
  }
}
@@switch
import { Module } from '@nestjs/common';
import { createDatabaseProviders } from './database.providers';
import { Connection } from './connection.provider';

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

info 힌트 forRoot()메소드는 동적 모듈을 동기식 또는 비동기식으로 (즉, Promise를 통해) 반환 할 수 있습니다.

이 모듈은 기본적으로 연결 공급자를 정의하지만, 추가 된 엔티티옵션 오브젝트에 따라 공급자 콜렉션 (예: 저장소)을 노출합니다. 동적 모듈은 기본 모듈 메타 데이터를 재정의하지 않고 확장합니다. 이것이 정적으로 선언 된 연결 공급자 동적으로 구성된 저장소 공급자가 모두 모듈에서 내보내는 방법입니다.

이 실질적인 기능은 공급자를 동적으로 등록하고 구성해야 할 때 유용합니다. 이런 식으로 정의하면 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 AppModule {}

동적 모듈을 다시 내보내려면 exports 배열에서 forRoot()메소드 호출을 생략 할 수 있습니다.

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 AppModule {}

Last updated