MODULE SYSTEMS

ESM과 CommonJS

모듈 문법의 차이는 역사 문제가 아니라 정적 분석, live binding, default interop, 순환 참조 처리에서 실제 빌드와 런타임 결과를 바꾼다.

01

의존성 수집

ESM은 import를 정적으로 분석해 번들러가 tree shaking을 하기 쉽다.

static graph
02

실행 순서

모듈은 한 번 평가되고 export binding을 다른 모듈이 참조한다.

single evaluation
03

바인딩 갱신

ESM named export는 값 복사가 아니라 live binding처럼 변경을 반영한다.

live binding
04

상호운용

CJS default와 ESM named export를 섞을 때 빌드 설정별 결과를 확인한다.

interop
require()
조건부 런타임 로드 가능 if문 안에서 부를 수 있지만 정적 최적화에는 불리하다.
dynamic
import
파일 상단 정적 선언 번들러가 의존성 그래프를 미리 알고 분리와 제거를 수행할 수 있다.
tree shaking
module.exports
객체를 내보냄 ESM에서 default import로 받을 때 도구별 interop 결과가 다를 수 있다.
interop risk
circular
순환 참조 초기화 차이 아직 초기화되지 않은 binding에 접근하면 undefined 또는 TDZ 오류가 날 수 있다.
cycle design

마이그레이션 기준

package type package.json type, 파일 확장자 .mjs/.cjs가 의도와 맞는지 본다.
default import CJS 라이브러리를 ESM에서 가져올 때 실제 객체 형태를 로그로 확인한다.
tree shaking named export로 바꾼 뒤 사용하지 않는 코드가 번들에서 빠지는지 분석한다.