본문 바로가기
CS 질문

[Deep Dive] CJS와 ESM의 차이에 대해서 알고 계신가요?

by 민챙이_99 2026. 2. 12.

많은 개발자가 require는 구식, import는 신식이라고 생각하곤 합니다. 하지만 프로젝트를 구축하거나 복잡한 라이브러리 의존성 문제를 해결하다 보면, 이 둘의 차이가 단순히 문법(Syntax)의 문제가 아니라 모듈을 로드하고 해석하는 '근본적인 메커니즘'의 차이 라는 것을 깨닫게 됩니다. 

 

오늘은 그 핵심은 동기적 실행(CJS)과 정적구조(ESM)의 차이에 대해서 정리해보도록 하겠습니다. 

 

먼저 여기에서 말하는 용어에 대해서 먼저 정리하고 가겠습니다. 

[용어정리]

  • 비동기적 : 실행 시점에 모듈을 가져온다. 모듈 파일을 네트워크나 디스크에서 가져오는 동작(런타임에서 동작)
  • 정적 분석 : 실행 전에 구조를 파악한다. 코드를 실행하지 않고, import/export 문만 읽어서 "어떤 모듈이 어떤 모듈을 필요로 하는지" 파악하는 것. (코드 실행 전에 동작)

 

1. CommonJS (CJS): 실행해봐야 아는 '동기적' 모듈

CJS는 Node.js의 탄생과 함께 서버 사이드 자바스크립트를 위해 설계 되었습니다. 가장 큰 특징은 런타임(실행 시점)에 모듈을 동기적으로 로드한다는 점입니다. 

  • 동기적 로딩 : require()가 호출되는 순간, 스크립트를 즉시 읽고 실행합니다. 
  • 동적 결정 : 실행 시점에 모듈을 결정하기 때문에 if 조건문 안에서 require를 호출하거나, 변수를 인자로 넣는 것이 가능합니다. 
  • 복사(Value Copy) : 값을 내보낼 때 당시의 상태를 복사해서 전달합니다. 즉, 원본 모듈 내부의 값이 바뀌어도 가져간 쪽의 값은 변하지 않습니다. 

 

2. ESM: 실행 전에 이미 결정된 '정적'구조

반면 ESM은 브라우저 표준을 지향하며 등장했습니다. ESM이 '비동기적'으로 동작할 수 있는 이유는 역설적으로 그 구조가 '정적(Static)'이기 때문입니다. 

  • 3단계의 로딩 과정 : ESM은 구성(Construction) → 인스턴스화(Instantiation) → 실행(Evaluation) 단계를 거칩니다.
  • 정적 분석 (Static Analysis) : 코드를 실행하기 전(컴파일 타임)에 이미 모듈 간의 의존성 그래프를 완성합니다. import가 항상 최상단에 있어야 하는 이유가 바로 이 '정적 구조'를 유지하기 위해서 입니다. 
  • 참조(Live Binding) : 값이 아닌 메모리 주소를 공유합니다. 모듈 내부의 값이 변하면 이를 참조하는 모든 곳에서 실시간으로 반영된 값을 보게 됩니다. 

 

3. 보통, ESM을 사용하는 이유가 최적화 때문인데요,  어떤부분을 최적화 하는지 한번 알아보겠습니다. 

① 트리 쉐이킹(Tree Shaking)의 가능 여부

  • CJS : 실행 전에는 어떤 코드가 쓰일지 알 수 없습니다. 따라서 번들러는 안전을 위해 모든 코드를 포함시키고, 결과적으로 번들 사이즈가 커집니다. 
  • ESM : 정적 분석 덕분에 빌드 타임에 "이 컴포넌트는 절대 안 쓰인다"는 것을 확신하고 제거할 수 있습니다. 

② Top-level Await와 상호운용성

ESM은 실행 전 인스턴스화 과정을 거치므로, 최상위 단계에서 await를 사용할 수 있습니다. 이는 비동기적으로 데이터를 초기화해야 하는 최신 라이브러리 설계에 매우 유리합니다.

// dbConnect.js (ESM)
export const db = await initializeDB(); // 여기서 딱 멈춰서 기다려줍니다.

// main.js
import { db } from './dbConnect.js'; 
console.log(db); // 보장된 데이터를 안전하게 바로 사용!

 

핵심) ESM은 이 await가 끝날 때까지 해당 모듈을 import한 다른 모듈들의 실행을 잠시 멈춰줍니다. 덕분에 비동기 초기화가 필요한 디자인 시스템의 테마 데이터나 설정값을 훨씬 안전하게 다룰 수 있습니다. 

 

 

ESM은 단순히 신기술이라서가 아니라, 웹 환경의 표준을 준수하고 정적 분석을 통해 최상의 성능(트리 쉐이킹)을 내기 위한 필연적인 선택이라고 생각합니다. 

 

 

참고)
https://www.joseph0926.com/post/2026-02-10-how-can-esm-be-statically-analyzed-despite-being-asynchronous

https://medium.com/@sojjung3/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EB%AA%A8%EB%93%88-cjs%EC%99%80-esm%EC%9D%98-%EC%B0%A8%EC%9D%B4-d133660d01a8

'CS 질문' 카테고리의 다른 글

[Deep Dive CS - Q30] Web Accessibility  (0) 2025.12.22
[Deep Dive CS - Q28] Rendering  (1) 2025.12.22
[Deep Dive CS - Q27] CRP  (0) 2025.12.22
[Deep Dive CS - Q27] 코드리뷰  (0) 2025.12.22
[Deep Dive CS - Q25,Q26] Promise  (0) 2025.12.18