배럴 파일의 순환 의존성 문제로 인한 Next.js 핫 리로딩 시 서비스 정지 문제

작성 : 2024-09-12수정 : 2024-09-12

목차 펼치기

 출처:  위키백과 - 우로보로스

머리말

Next.js 14에서 개발하는 도중 커스텀 훅과 API 함수 폴더에 배럴 파일(여러 모듈을 한 곳에서 export 하는 방식)을 적용한 이후로 발생한 핫 리로딩 시 사이트 멈춤 문제를 겪은 내용에 대한 글입니다.



배경 및 증상

어느 순간부터 간헐적으로 핫 리로딩 시 사이트가 멈추는 문제가 발생하기 시작했습니다. 새로운 탭을 띄워서 접속하면 정상적으로 동작하는 것을 보아 기능 상의 오류는 아닌 것 같았고, 어디서 메모리 누수가 발생하나 싶어 디버깅하기도 했지만 정확한 원인은 찾을 수 없었습니다. 그러던 중 유독 특정 폴더 내부에 선언된 파일만 수정하면 사이트가 멈춘다는 것을 알게 되었습니다.


특정 폴더 내 파일에서만 발생하는 점, 기능 이용에는 문제가 없고 파일 변경 시에만 문제가 발생하는 점을 근거로 파일 변경 내용을 적용하는 과정에서 문제가 있어 보였고, 어디선가 무한 루프가 발생하는 것이라 추정했습니다.


코드가 수정될 때마다 새로운 탭에서 확인해야하는 것은 개발 생산성에 매우 안좋은 영향을 끼치기 때문에 조속한 수정이 필요했습니다.


원인 및 문제

배럴 파일을 통한 참조 시 발생하는 순환 의존성 문제로 인한 Next.js 핫 리로딩 시 서비스 정지 문제

문제를 인지하기 얼마 전, 전반적으로 배럴 파일을 적용하는 리팩터링을 진행했었는데 이 작업이 가장 의심스러웠습니다. 당시에 배럴 파일은 import 문을 간결하게 해주고, 모듈 경로의 변경을 자유롭게 해준다는 장점만 생각해서 여러 폴더에 적용했었는데, 이를 통한 참조 과정에서 문제가 발생하는 것으로 생각되었습니다.


index.ts

와 export 파일들이 같은 계층에 존재하기도 했는데, Nest.js 에서 이 패턴을 사용하면 순환 의존성 문제가 발생할 수 있다는 내용의 문서도 확인할 수 있었습니다. 비록 Nest.js는 아니었지만, 무분별하게 사용하여 문제가 발생할 수도 있는 패턴임에는 더 분명해졌습니다.


해결

배럴 파일을 모두 제거하고, 사용하는 파일을 직접 import 하는 방식으로 모두 수정하여 해결되었습니다.


생각

결국 배럴 파일로 인한 문제였고 이를 제거함으로써 해결할 수 있었지만, 정확히 어떤 원리로 인해 순환 참조 문제가 발생하는 지는 알 수 없었고 귀납적으로 추리해 볼 뿐이었습니다. 지금 생각하기로는 커스텀 훅이나 API 호출 모두 서로 같은 계층을 참조하는 로직이 많았기 때문에 발생했다고 생각됩니다. 동일 계층의

index.ts

파일을 제거하여 계층을 추가하는 방식도 적용해보았으나 문제는 해결되지 않았고 결국 커스텀 훅 폴더와 API 함수 폴더 내에서 배럴 파일을 모두 제거할 수 밖에 없었습니다.


배럴 파일을 제거하기 위해서는 적용된 모든 곳의 import를 고쳐야하는 지루한 반복 노가다 작업이 따릅니다. 이번에는 규모가 크지 않고 Cursor Copilot++의 자동 코드 제안 덕분에 그나마 빠르게 수정할 수 있었지만, 프로젝트의 규모가 클수록 수정이 오래 걸렸을 것입니다.


배럴 파일은 export/import를 단순화해서 관리할 수 있다는 명확한 장점이 존재하지만, 프로젝트의 모든 폴더에서 사용할 경우 성능 저하나 순환 의존성 등의 문제를 발생시킬 수 있다는 걸 경험했습니다. 앞으로는 무분별하게 모든 경로에 배럴 파일을 사용해서 import 하는 것은 지양하고 컴포넌트, 상수, 유틸리티 등의 일부 경로에만 배럴 파일을 적용하는 고려하게 되었습니다.


배럴 파일의 장점도 명확히 존재하지만 Lint를 통해 import 구문의 정렬과 그룹화를 설정하는 것으로도 어느 정도의 가독성은 확보할 수 있고, 참조 대상 파일의 경로를 변경할 경우 IDE가 자동으로 갱신해주기도 하니 이런 방식으로도 충분히 DX를 확보할 수 있겠다는 생각이 들기도 합니다.


같이 참고하면 좋은 글

Wanna get in touch?

All Icons byiconiFy