NestJS 순환 종속성 문제(상호참조)

권태형·2023년 5월 24일
0

bnb Back-Server Project

목록 보기
10/31
post-thumbnail

프로젝트를 진행 중 아래와 같은 에러가 발생하였다.

Error: Nest cannot create the ReservationsModule instance.
Potential causes:

  • A circular dependency between modules. Use forwardRef() to avoid it. Read more: https://docs.nestjs.com/fundamentals/circular-dependency
  • The module at index [2] is of type "undefined". Check your import statements and the type of the module.

A circular dependency between modules 즉 서로의 모듈간 상호 순환 의존성이 발생하였고, forwardRef()를 써서 방지해라. 라는 뜻이다.

NestJS공식문서의 Circular dependency 페이지로 가서 내용을 확인했다.

//cats.service.ts
@Injectable()
export class CatsService {
  constructor(
    @Inject(forwardRef(() => CommonService))
    private commonService: CommonService,
  ) {}
}
//common.service.ts
@Injectable()
export class CommonService {
  constructor(
    @Inject(forwardRef(() => CatsService))
    private catsService: CatsService,
  ) {}
}

공식페이지에서는 forwardRef()@nestjs/common에서 끌고와서 위와같이 서로 참조하는 부분에 사용하면 해결할 수 있다고 적혀있어서 그대로 진행해보았다.

//house.service.ts
@Injectable()
export class HousesService {
  constructor(
    @InjectRepository(House) private houseRepository: Repository<House>,
    private dataSource: DataSource,
    @Inject(forwardRef(() => ReservationsService))
    private reservationService: ReservationsService,
  ) {}
  //....//
}
//reservation.service.ts
@Injectable()
export class ReservationsService {
  constructor(
    @InjectRepository(Reservation)
    private reservationRepository: Repository<Reservation>,
    @Inject(forwardRef(() => HousesService))
    private housesService: HousesService,
  ) {}
  //....//
}

하지만 똑같은 에러를 반환하였다. 공식페이지의 내용을 더 읽어보니 모듈간 순환 종속성을 해결하기 위해서 모듈에서 아래와 같이 작성해야한다고 적혀있었다.

//common.module.ts
@Module({
  imports: [forwardRef(() => CatsModule)],
})
export class CommonModule {}

마찬가지로 해당 내용을 적용해 보았더니 해결되었다.

//house.module.ts
@Module({
  imports: [
    TypeOrmModule.forFeature([House]),
    forwardRef(() => ReservationsModule),
  ],
  controllers: [HousesController],
  providers: [HousesService],
  exports: [HousesService],
})
//reservation.module.ts
@Module({
  imports: [
    TypeOrmModule.forFeature([Reservation]),
    AuthModule,
    forwardRef(() => HousesModule),
  ],
  controllers: [ReservationsController],
  providers: [ReservationsService],
  exports: [ReservationsService],
})

혹시나 싶어 먼저 진행했던 Service에서 사용된 forwardRef()를 기존 방식으로 변경해 보았는데, 다시 에러를 뿜었다. 결국 Service에서도 Module에서도 모두 사용해 줘야만 해결되는 방식이었다.

해결은 하였지만 이해가 도통가지 않았다. forwardRef()를 step-in 해보면 아래와 같다.

import { ForwardReference } from '../interfaces/modules/forward-reference.interface';
/**
 * @publicApi
 */
export declare const forwardRef: (fn: () => any) => ForwardReference;

export interface ForwardReference<T = any> {
    forwardRef: T;
}

대체 이 함수가 뭘.. 할 수 있는거지? 어째서 순환참조를 해결해 주는건지 알 수 없었다.. 찜찜한데 찾아봐도 잘 안나와서 일단은 해결은 됬으니 넘어는 간다.. ㅠㅠ

profile
22년 12월 개발을 시작한 신입 개발자 ‘권태형’입니다. 포스팅 하나하나 내가 다시보기 위해 쓰는 것이지만, 다른 분들에게도 도움이 되었으면 좋겠습니다. 💯컬러폰트가 잘 안보이실 경우 🌙다크모드를 이용해주세요.😀 지적과 참견은 언제나 환영합니다. 많은 댓글 부탁드립니다.

0개의 댓글