본문 바로가기
FrameWork & Runtime/Node.js (NestJs)

모듈 [ @Module() ]

by jaeaemin 2022. 7. 28.

@Module() 데코레이터의 역할 :

Nest 가 애플리케이션 구조를 만들 때 사용할 수 있는 메타 데이터를 생성하고 Nest는 이를 기반으로 애플리케이션 구조를 생성한다. 

https://docs.nestjs.com/modules

  • 각 응용 프로그램은 하나 이상의 루트 모듈을 가진다. ( 애플리케이션을 구성하기 위한 시작점 ) 
  • 애플리케이션이 커지면 컴포넌트를 분리하고, 여러개의 컴포넌트를 구성하기 위해 여러 모듈을 활용함 
  • 주로 관련 기능을 묶어 캡슐화하는 모듈을 선언하고 이를 활용한다.\

 

 

@Module() 데코레이터의 속성 종류

providers  Nest의 인젝터가 인스턴스화시키고 적어도 이 모듈안에서 공유하는 프로바이더
( 인젝터란 의존성을 주입하는 Nest의 내부 모듈 ) 
controllers 모듈안에서 인스턴스화를 목적으로 정의된 컨트롤러의 집합
imports 해당 모듈에서 필요한 모듈의 집합 
exports 해당 모듈에서 제공하는 프로바이더의 부분집합 
모듈은 기본적으로 프로바이더를 캡슐화합니다. 즉, 현재 모듈에 직접 속하지 않거나 가져온 모듈에서 노출(export)하지 않는 프로바이더를 주입할 수 없습니다. 따라서 모듈에서 노출한 프로바이더를 모듈의 공용 인터페이스 또는 API로 간주할 수 있습니다.

 

 

기능 모듈  생성

CatsController , CatsService는 둘다 고양이라는 공통된 기능을 가지고 있기 때문에 같은 도메인이라 할 수 있다.

이는 기능 모듈로 분류하는 것이 좋다.

기능 모듈은 특정 기능과 관련된 코드를 구성하여 코드를 체계적으로 유지하고 명확한 경계를 설정한다.

 

 

## cat module

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

위의 코드에서 모듈의 컨트롤러와 프로바이더를 선언하고, CatsModule로 export 하였다.

이제 모듈 생성을 완료했으니, 이 모듈을 루트 모듈 파일에서 가져온다. 

 

// app.module.ts

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

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

 

공유 모듈

Nest에서 기본적으로 모듈을 싱글톤이디. 때문에 NEST에서는 여러 모듈 간 쉽게 공급자와 동일한 인스턴스를 공유할 수 있다.

"모든 모듈은 자동으로 공유 모듈로 설정되고, 생성되면 모든 모듈에서 재사용할 수 있다. " 

아래의 예는 아까전 생성한 CatsService 인스턴스를 다른 모듈간의 공유하는 예시이다.

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

 

이렇게 선언한 이후에 import { CastsModule } from './cats/cats.module 을 통해서 모듈을 가져온 다른 모듈은

"CatsService"에 접근할 수 있고 이 모듈을 가져오는 다른 모듈과 동일한 인스턴스를 공유한다.

 

 

 

의존성 주입 

- 모듈 클래스도 프로바이더를 주입할 수 있다. ( 예로 설정관련된 목적으로 활용 ) 

// 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 catsService: CatsService) {}
}

 

 

전역 모듈 

Nest에서는 프로바이더는 모듈을 벗어날 수 없기 때문애, 전역적으로 프로바이더를 등록할 수 없다.

해당 프로바이더를 다른 곳에서 사용하기 위해서는, 해당 프로바이더가 속한 모듈을 먼저 가져와야 한다.

어디서나 사용 가능한 프로바이더를 제공하기 위해서는 @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 프로바이더는 어디서나 사용할 수 있으며, CatsService 서비스를 주입하려는 모듈은 CatsModule을 모듈의 import 배열에 추가할 필요가 없음 ( 하지만 좋은 디자인 패턴은 아니다 ! ) 

 

 

 

 

동적 모듈 

반응형

'FrameWork & Runtime > Node.js (NestJs)' 카테고리의 다른 글

[NestJs] Controller  (0) 2024.04.26
TypeORM  (0) 2022.10.03