CommonJS와 ES Module(ESM) 은 자바스크립트에서 모듈을 관리하고 불러오는 두 가지 주요 방식입니다.
Common JS는 Node.js에서 주로 사용되는 모듈 시스템으로, 모듈을 동기적으로 불러옵니다.
require() 키워드로 모듈을 불러오고, module.export로 내보냅니다.
이 방식은 주로 서버측에서 사용 됐지만, 클라이언트 환경에서도 번들러를 통해 사용할 수 있습니다.
특징
서버 환경(서버 사이드 렌더링)에 적합.
동적 로드로 런타임 의존성 처리.
트리 쉐이킹 어려움 (정적 분석 불가).
브라우저에서는 Webpack, Rollup 등 번들러 필요.
트리 셰이킹은 사용되지 않는 코드를 제거하여 번들 크기를 줄이는 기술
// math.js
module.exports = { add: (a, b) => a + b };
// main.js
const { add } = require("./math");
console.log(add(1, 2)); // 3
ES Module은 자바스크립트의 공식 표준 모듈 시스템으로, ECMAScript 2015(ES6)부터 도입되었습니다. ESM은 브라우저와 Node.js 환경에서 모두 사용할 수 있으며, 모듈을 비동기적으로 로드합니다.
모듈을 가져올 때는 import 키워드를 사용하고, 내보낼 때는 export를 사용합니다. 또한, ESM은 정적 분석이 가능해, 트리 쉐이킹과 같은 최적화 작업에도 유리합니다.
특징
브라우저와 Node.js(12+부터 네이티브 지원)에서 사용.
정적 분석으로 트리 쉐이킹 가능 (번들 크기 최적화).
<script type="module">로 브라우저에서 네이티브 지원.
풀스택 개발에서 모듈 호환성 우수.
// math.js
export const add = (a, b) => a + b;
// main.js
import { add } from "./math.js";
console.log(add(1, 2)); // 3
CommonJS와 ES Module은 자바스크립트의 모듈 시스템입니다.
CommonJS는 Node.js에서 사용되며, require와 module.exports로 동기적으로 모듈을 로드합니다. 서버 환경에 적합하지만, 트리 쉐이킹이 어렵고 브라우저에서는 번들러가 필요합니다.
ES Module는 ES6 표준으로, import와 export를 사용해 비동기적으로 로드합니다. 브라우저와 Node.js에서 지원되며, 정적 분석으로 트리 쉐이킹이 가능해 성능 최적화에 유리합니다.
ESM은 비동기 로드와 호환성 덕분에 풀스택 개발에서 점차 선호됩니다. 예를 들어, Zustand 같은 상태 관리 라이브러리는 ESM으로 최적화됩니다.
둘의 차이점은 CommonJS는 주로 동기적이고 서버 측에서 많이 사용되며,ESM은 비동기적이고 브라우저와 서버 모두에서 사용할 수 있다는 점 입니다.
트리 쉐이킹이 ESM에서 쉬운 이유는?
ESM은 정적 import/export로 파싱 단계에서 의존성을 분석할 수 있어, 미사용 코드를 제거하기 쉽습니다. CommonJS는 동적 require로 런타임에 의존성을 결정해 분석이 어렵습니다.
CommonJS와 ESM을 함께 사용할 수 있나요?
Node.js에서는 CommonJS와 ESM을 혼용할 수 있지만, 주의가 필요합니다. ESM에서 CommonJS 모듈을 import로 가져올 수 있고, CommonJS에서 ESM을 동적 import()로 로드할 수 있습니다. 하지만 파일 확장자(.js vs .mjs)와 package.json의 "type": "module" 설정을 명확히 해야 호환성 문제가 없습니다.
Node.js에서 ESM과 CommonJS 혼용 시 주의점은?
ESM에서 CommonJS는 createRequire나 동적 import()로 가져오고, CommonJS에서 ESM은 import()로 로드합니다. package.json의 "type": "module" 설정과 확장자(.js vs .mjs)를 명확히 해야 합니다.
브라우저에서 CommonJS를 사용하려면?
브라우저는 CommonJS를 지원하지 않으므로, Webpack이나 Rollup 같은 번들러를 사용해 CommonJS 모듈을 ESM이나 브라우저 호환 코드로 변환해야 합니다. 번들러는 require를 처리하고 모듈을 단일 파일로 묶습니다.
Node.js에서 ESM을 사용하려면 어떤 설정이 필요한가요?
파일 확장자를 .mjs로 설정하거나,
package.json에 "type": "module"을 추가.
기본값은 CommonJS("type": "commonjs")이므로, 명시적 설정 필요.
.js 파일도 "type": "module"이면 ESM으로 처리.
ESM의 비동기 로드는 렌더링에 어떤 영향을 미치나?
ESM은<script type="module">로 비동기 로드되어 HTML 파싱과 병렬 처리되며, defer처럼 파싱 후 실행됩니다. 이는 초기 렌더링 속도를 개선합니다.
실무에서 ESM을 선호하는 이유는?
ESM은 브라우저와 Node.js 호환, 트리 쉐이킹, 비동기 로드로 성능과 유지보수가 우수합니다. Vite, Next.js 같은 현대 프레임워크도 ESM 중심입니다.
ESM의 정적 분석은 어떤 이점이 있나요?
ESM의 정적 분석은 import/export가 런타임이 아닌 파싱 단계에서 처리되므로, 빌드 도구가 의존성을 미리 분석해 트리 쉐이킹, 데드 코드 제거, 최적화를 수행할 수 있습니다.
CommonJS와 ESM의 성능 차이는?
ESM은 비동기 로드와 정적 분석으로 트리 쉐이킹이 가능해 번들 크기와 로드 속도를 최적화할 수 있습니다. CommonJS는 동기 로드로 서버 환경에서는 빠를 수 있지만, 브라우저에서는 번들러 의존도가 높아 성능이 저하될 수 있습니다.