Post

(TIL) 2024-12-17

(TIL) 2024-12-17

Circular Dependency(순환 의존성)


모듈 간 의존성이 원형 구조를 이루는 상황을 말한다. 즉, 모듈 A가 모듈 B를 의존하고, 모듈 B가 다시 모듈 A를 의존하는 경우이다. 이러한 순환 의존성은 코드를 복잡하게 만들고, 런타임 에러나 예기치 않은 동작을 유발할 수 있다.

1
2
3
4
5
6
7
// fileA.js
import { valueB } from './fileB.js';
export const valueA = `A and ${valueB}`;

// fileB.js
import { valueA } from './fileA.js';
export const valueB = `B and ${valueA}`;

문제점

  1. 값 초기화 문제: 자바스크립트의 모듈 시스템(특히 ES 모듈)은 호이스팅(hoisting) 덕분에 순환 참조를 감지하고 실행하지만, 일부 의존성은 초기화되지 않을 수 있다.
  2. 디버깅의 어려움: 의존성이 꼬여 있어 디버깅하기 어렵고, 어디서 문제가 발생했는지 파악하기 힘들다.
  3. 모듈 크기의 증가: 순환 의존성이 있는 모듈은 다른 모듈로부터 계속 로딩되어 불필요한 의존성이 추가될 수 있다.
  4. 성능 문제: 코드가 복잡해지고 의존성 관리가 비효율적으로 이루어질 가능성이 있다.

해결방법

  1. 디자인 패턴 변경
    • 순환 의존성을 피하기 위해 모듈 의존성을 재설계하ㅡㄴ다다. 예를 들어, 의존성 중 일부를 중앙 관리 모듈로 분리할 수 있다.
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      
       // central.js
       export const sharedValue = 'Shared';
      
       // fileA.js
       import { sharedValue } from './central.js';
       export const valueA = `A and ${sharedValue}`;
      
       // fileB.js
       import { sharedValue } from './central.js';
       export const valueB = `B and ${sharedValue}`;
      
  2. 의존성 주입 (Dependency Injection)
    • 모듈 의존성을 동적으로 주입하여 순환 참조를 피해야한다.
      1
      2
      3
      4
      5
      6
      7
      
       // fileA.js
       export const getValueA = (valueB) => `A and ${valueB}`;
      
       // fileB.js
       import { getValueA } from './fileA.js';
       const valueB = 'B';
       export const valueA = getValueA(valueB);
      
  3. 공통 인터페이스 사용
    • 순환 참조가 필요한 경우, 모듈 간 직접적인 참조 대신 인터페이스를 사용하여 간접적으로 연결한다.
      1
      2
      
       // interface.js
       export const getValue = () => {};
      
  4. ES 모듈의 Import 규칙 활용
    • 자바스크립트 ES 모듈에서는 “임포트한 값이 미리 선언되지 않으면 undefined를 반환”한다. 이를 고려해 순환 참조를 최소화하거나 런타임 중 의존성을 재설정한다.

결론

순환 의존성은 복잡한 모듈 시스템에서 자주 발생할 수 있는 이며, 이를 피하려면 의존성의 방향성을 설계하고, 재사용 가능한 구조를 만들어야 한다.
코드를 작성할 때 순환 의존성을 사전에 방지하고, 정적 분석 도구를 통해 감지하는 것이 중요하다.

This post is licensed under CC BY 4.0 by the author.