[NestJS] 모듈(Module) 이란?
![[NestJS] 모듈(Module) 이란?](/_next/image?url=https%3A%2F%2Fdonghyuncc-cloudfront-aws.ncloud.sbs%2F6bbb6836-34ba-4749-bee0-83e70d9a799e.png&w=3840&q=75)
백엔드 코드가 커질수록 아키텍처에 대한 고민이 많아진다.
NestJS는 이 아키텍처를 정의해준다.
그 정의하는 아키텍쳐로 nestJS에서는 Module(모듈)이라는 개념을 사용한다.
모듈이란?
모듈은 @Module() 데코레이터가 붙은 클래스다. 단
순한 클래스 묶음이 아니라, Nest가 애플리케이션 전체 구조를 이해하는 단위다.

Nest는 앱 실행 시 이 트리를 분석해 의존성 그래프를 구성한다. 어떤 서비스가 어디서 쓰이는지, 무엇을 공유하고 무엇을 캡슐화하는지를 이 그래프로 관리한다.
ExpressJS와 비교하면
| 구분 | Express | NestJS |
|---|---|---|
| 구조 규칙 | 없음 (자유) | 모듈 단위로 정해져 있음 |
| 의존성 관리 | 수동 import | DI 컨테이너 자동 처리 |
| 코드 탐색 | 팀/개인마다 다름 | 항상 예측 가능 |
| 테스트 격리 | 직접 구성 | 모듈 단위 격리 기본 제공 |
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 | 환경·옵션에 따라 다르게 구성해야 할 때 |