공유모듈을 사용하다가 에러가 떠서 @Module에 대해서 스터디하고 해결까지 완료한 내용을 포스팅 해보려고 한다.
우선 @Module을 먼저 알아보자.
Module 이란 무엇인가?
각 애플리케이션에는 최소한 하나의 모듈인 루트 모듈이 있습니다 . 루트 모듈은 Nest가 애플리케이션 그래프를 구축하는 데 사용하는 시작점입니다 . Nest가 모듈과 공급자 관계 및 종속성을 해결하는 데 사용하는 내부 데이터 구조입니다. 매우 작은 응용 프로그램은 이론적으로 루트 모듈만 가질 수 있지만 일반적인 경우는 아닙니다. 구성 요소를 구성하는 효과적인 방법으로 모듈을 강력하게 권장 한다는 점을 강조하고 싶습니다 . 따라서 대부분의 애플리케이션에서 결과 아키텍처는 각각 밀접하게 관련된 기능 집합을 캡슐화하는 여러 모듈을 사용합니다 .
Nest 공식문서에는 Module에 대해 이처럼 나와 있다.
쉽게 설명해보자면
클래스에 @Module 데코레이터를 붙혀 선언하며 모든 Nest 어플리케이션에는 최소 한개의 root 모듈을 가진다.
컴포넌트들을 구조화하기 위해서 기능과 역할에 맞춰서 모듈화 해줘야 한다.
- imports
- 현재 모듈에서 import할 모듈들을 포함하는 배열
- import 할 외부모듈들은 해당 모듈에서 Provider를 export 해줘야 함
- 주로 entity파일이나 다른 모듈이 들어감
- controllers
- 이 모듈에서 사용할 Controller들을 포함하는 배열
- providers
- 이 모듈에 집어넣을 Provider들을 포함하는 배열
- Nest injector(@Injectable)에 의해 인스턴스화되고 적어도 이 모듈에서 공유 될 수있는 provider
- 주로 service부, repository부
- exports
- 다른 모듈에서 import 해서 사용할 Provider들을 포함하는 배열
간단한 개념이지만 이 내용을 대충알고 넘겼어서 에러가 발생했다.
상황은 VotesModule에서 commentService를 사용해야되는 케이스였다.
이럴경우 각각의 Module에서 관련정보를 작성해줘야 되는데 아주 내멋대로 써버려서 이같은 오류가 발생했다.
ERROR [ExceptionHandler] Nest can't resolve dependencies of the CommentService (?). Please make sure that the argument CommentQueryRepository at index [0] is available in the VotesModule context.
Potential solutions:
- Is VotesModule a valid NestJS module?
- If CommentQueryRepository is a provider, is it part of the current VotesModule?
- If CommentQueryRepository is exported from a separate @Module, is that module imported within VotesModule?
@Module({
imports: [ /* the Module containing CommentQueryRepository */ ]
})
그래서 Module쪽 스터디를 하고 다시 개발을 했다.
CommentModule에서는 CommentService를 exports해주고
VotesModule에서는 CommentModule를 import 해주면 끝이다.
여기서 잠깐..!
이런 질문을 할 수도 있다.
VotesModules import에 바로 CommentService를 넣으면 되지 않나요..?
답은, 그렇게 해도 코드상에는 문제가 없다.
하지만 CommentService 자체를 넣게되면 계속해서 객체가 인스턴스화 되어 메모리에 쌓이게 된다.
이렇게되면 불필요한 메모리를 차지하게 되므로 결국 성능에 영향을 끼친다.
결국 성능을 고려한 코드를 짜야 하므로 CommentModule를 import 시켜주도록 하자.