JavaScript 모듈을 나눴더니 순환 import에서 초기화 오류가 납니다. 모듈의 바인딩과 실행 순서는 어떻게 보나요?
잠깐, 답변을 보기 전에
먼저 내 말로 설명해 볼까요?
답변과 점검 포인트 펼치기답변 접기
구두 답변
정의를 외우기보다, 원리와 조건을 연결해 설명해 보세요.
모듈의 연결과 값 초기화는 별도 단계이며 순환 의존에서는 상대 모듈의 값이 아직 초기화되지 않은 시점에 접근할 수 있습니다. import가 있다는 사실만으로 모든 export 값이 사용 준비됐다는 뜻은 아닙니다.
동작 원리와 전제
ES module의 live binding과 TDZ를 이해하고 top-level에서 상대 값을 즉시 읽는 순환을 찾습니다. CommonJS와 ESM의 순환·캐시 동작을 같은 것으로 설명하지 않습니다. bundler가 증상을 바꾸더라도 논리적 의존 문제는 남을 수 있습니다.
선택과 실패 처리
공통 타입·순수 함수·상수 경계를 분리하거나 초기화 조립을 시작점으로 옮겨 순환을 줄입니다. 지연 호출로 해결할 수 있어도 호출 시점의 초기화 전제를 문서화합니다. 전역 singleton의 생성 순서가 숨은 의존성을 만들지 않는지 봅니다.
구체적인 사례와 검증
A 모듈의 초기값이 B의 export를 즉시 읽고 B의 초기값도 A를 즉시 읽으면 적어도 한쪽은 초기화 전 접근이 될 수 있습니다. 함수 정의만 서로 참조하고 실제 호출은 초기화 뒤에 하는 경우와 구분해야 합니다. 문제를 숨기기 위해 import 순서를 우연히 바꾸기보다 공통 책임을 별도 모듈로 옮기거나 조립 시점에 값을 전달합니다. 테스트에서 모듈 캐시가 이미 채워져 오류가 안 보일 수 있어 새 프로세스의 cold import도 확인합니다. bundler의 tree shaking·변환이 실행 순서를 바꿀 수 있으므로 실제 배포 형식에서 재현하겠습니다.
직접 실행·번들·테스트 환경과 import 순서를 바꾸어 시험합니다. 모듈 캐시를 초기화하는 테스트가 운영과 다른 상태를 만들 수 있어 주의합니다. 파일 분리 자체보다 의존 방향과 초기화 수명이 명확한지가 핵심입니다.
득점 포인트
이해가 드러나는 지점을 확인해 보세요.
- 핵심 구분: 모듈의 연결과 값 초기화는 별도 단계이며 순환 의존에서는 상대 모듈의 값이 아직 초기화되지 않은 시점에 접근할 수 있습니다.
- 선택 조건: 공통 타입·순수 함수·상수 경계를 분리하거나 초기화 조립을 시작점으로 옮겨 순환을 줄입니다.
- 검증 기준: 직접 실행·번들·테스트 환경과 import 순서를 바꾸어 시험합니다.
감점 포인트
놓치기 쉬운 조건과 오해를 짚어 보세요.
- import가 연결되면 순환 모듈의 모든 export 값도 이미 초기화됐다고 한다.
더 파고들 거리
하나 더 질문하며 이해의 범위를 넓혀 보세요.
- 바인딩 생성과 초기화가 다른 시점일 때 선언 전 접근이 어떤 결과를 내나요?
- 객체 하나의 초기화 안전성과 이후 가변 상태·종료 순서는 어떻게 구분하나요?
- 순환된 구현 의존을 정책이 소유하는 좁은 인터페이스로 어떻게 바꾸나요?
득점·감점 포인트는 학습용 자기 점검 기준이며, 특정 회사의 실제 채점표가 아닙니다.
원리부터 공부하고 싶다면
답변을 보충하는 개념·예제·슈도코드를 읽어 보세요.