[NestJS] 모듈(Module) 이란?

nodeJSnestJS
[NestJS] 모듈(Module) 이란?

백엔드 코드가 커질수록 아키텍처에 대한 고민이 많아진다.
NestJS는 이 아키텍처를 정의해준다.

그 정의하는 아키텍쳐로 nestJS에서는 Module(모듈)이라는 개념을 사용한다.


모듈이란?

모듈은 @Module() 데코레이터가 붙은 클래스다. 단
순한 클래스 묶음이 아니라, Nest가 애플리케이션 전체 구조를 이해하는 단위다.

image

Nest는 앱 실행 시 이 트리를 분석해 의존성 그래프를 구성한다. 어떤 서비스가 어디서 쓰이는지, 무엇을 공유하고 무엇을 캡슐화하는지를 이 그래프로 관리한다.


ExpressJS와 비교하면

구분ExpressNestJS
구조 규칙없음 (자유)모듈 단위로 정해져 있음
의존성 관리수동 importDI 컨테이너 자동 처리
코드 탐색팀/개인마다 다름항상 예측 가능
테스트 격리직접 구성모듈 단위 격리 기본 제공

Express가 나쁜 게 아니다. 다만 Express는 자유도가 높은 만큼, 구조를 올바르게 유지하는 책임이 팀에게 있다.
NestJS는 그 책임 중 구조 설계를 프레임워크가 가져간다.


@Module() 데코레이터

핵심은 캡슐화다. exports에 명시하지 않으면 외부 모듈에서 해당 프로바이더를 사용할 수 없다.
의도하지 않은 의존성이 생기는 것을 원천적으로 막는 구조다.


모듈의 네 가지 유형

상황마다 모듈을 구성하는 방식이 다르다. NestJS에서는 그 경우를 네 가지로 정의한다.

1. Feature Module

가장 기본적인 형태다. 하나의 도메인을 하나의 모듈로 묶는다.

a/ 폴더 안에 컨트롤러, 서비스, 모듈이 함께 위치하게 된다.
관련 코드를 찾기 위해 프로젝트 전체를 뒤질 필요가 없다.

2. Shared Module

별도의 구조가 있는 게 아니다. Feature Module에 exports를 추가한 순간 Shared Module이 된다.

exports에 추가하면 이 모듈을 imports한 어떤 모듈이든 AService를 주입받을 수 있다.
Nest에서 모듈은 기본적으로 싱글톤이므로, 여러 모듈에서 가져다 써도 인스턴스는 하나다.

3. Global Module

DB 연결, ConfigService 같은 것들은 매번 imports하기 번거롭다.
@Global() 데코레이터를 붙이면 한 번 등록으로 전체에서 사용 가능해진다.

단, 남용하면 안 된다. 모든 의존성을 전역으로 만들면 어디서 주입됐는지 추적이 어려워진다.
ConfigModule, DatabaseModule처럼 진짜 전역 공통 자원에만 적용하는 것이 일반적이다.

4. Dynamic Module

환경에 따라 설정이 달라지는 경우, 모듈 자체를 동적으로 구성할 수 있다.

TypeOrmModule.forRoot(), ConfigModule.forRoot() 등 NestJS 생태계의 주요 라이브러리가 모두 이 패턴을 쓴다.


정리

유형사용 예시
Feature Module도메인 단위 코드 분리
Shared Module여러 모듈에서 동일 서비스 재사용
Global Module앱 전역에서 쓰이는 공통 자원
Dynamic Module환경·옵션에 따라 다르게 구성해야 할 때