순환참조
: 서로를 참조하는 모듈끼리 서로 호출하는 타이밍과 서로 메모리에 로드되는 타이밍이 틀리면서
호출하고자 하는 모듈이 undefined가 되는 현상
발생 원인
: 프로그램의 시작점인 index.js에서 A 모듈을 참조하고 호출
: A 모듈은 B 모듈을 참조하고 호출
: B 모듈에서도 A 모듈을 참조하고 호출
발생 과정
1) A 모듈의 require(B모듈)을 읽으면서 코드 실행을 멈춘 뒤 B 모듈을 실행
2) B 모듈이 실행 되면서 require(A모듈) 부분에서 코드 실행을 멈춘 뒤 A 모듈을 실행
3) A 그룹 모듈이 실행 되면서 require(B모듈) 부분에서 코드 실행을 멈춘 뒤 B 모듈을 실행
4) B 모듈은 실행중 멈춘 상태이기 때문에 더 이상의 실행을 할 수 없어, module.exports의 기본 객체인 {}를 반환
5) A 모듈의 B 모듈 함수 호출 부분에서 {}를 호출하게 됨
6) B 모듈에서는 이미 정의 된 A 모듈의 module.exports를 할당 받아 코드가 실행됨
순환참조 해결 방법
- 지연선언
: 참조하는 모듈을 module.exports 보다 나중에 선언
: 순서 변경으로 인해 다른 곳에서 오류가 발생할 수 있음
- exports의 사용
: 각 모듈인 JavaScript 파일은 하나의 module.exports를 가지는데 기본적으로 {}를 가짐
: 모듈내에서 module.exports = { ... }를 하는 것은 module.exports를 재정의 하는 것임
: 이로인해 모듈을 require() 하면 양쪽 모듈의 실행이 끝나고나서 정상적인 객체가 반환됨
: Object.assign을 통해 module.exports를 하면 {}인 module.exports에 함수들을 복사하게 되면서 정상 작동
: 모듈이 다 로드되고나서 수행하던 module.exports에 대한 정의를
Object.assign을 통해 모듈 내의 함수들을 한 번 더 읽음으로써 정의
A 모듈의 파일 맨 하단 module.exports
Object.assign(module.exports, { '모듈a', '모듈b' })
B 모듈의 파일 맨 하단 module.exports
Object.assign(module.exports, { '모듈c', '모듈d' })
- 내부 모듈 패턴 사용
: 모든 모듈을 통합하는 하나의 파일을 생성하고 (ex) inner.js), index.js에서 해당 파일을 로드
: 모든 모듈들은 innder.js를 require하여 각 모듈간 필요한 함수 호출
※ 참조
: https://github.com/mobxjs/mobx/commit/e7f32aa0c2f6295b84270587285ab793b52d8643
정리
가장 좋은 방법은 순환 참조 구조를 없에는 것이다.
정 없에기 힘들다면 내부 모듈 패턴을 사용하여 한꺼번에 모든 모듈을 로드하고 불러내는 방법을 사용하는 것이
가장 좋은 방법인 것 같다. 메모리 차지에 얼마나 영향이 있는지는 좀 더 알아봐야할 것 같다.
Refference
'Programming > NodeJS' 카테고리의 다른 글
NodeJS의 메모리 누수 확인 방법 (0) | 2022.08.13 |
---|---|
NodeJS의 메모리 관리 방법 (V8 엔진과 가비지 컬렉션) (0) | 2022.08.13 |
NodeJS rest-client API JSON이 undefined로 나올때 (0) | 2022.07.30 |
vscode 이 시스템에서 스크립트를 실행할 수 없으므로 오류 해결법 (0) | 2022.07.30 |
yarn을 이용해 프로젝트 NODE_ENV 분기 실행 (0) | 2022.07.27 |