📘 CommonJS vs ESM (ES Modules)
CommonJS
와 ESM
(ES Modules)은 JavaScript의 모듈 시스템을 의미하며, 각각 서로 다른 방식으로 모듈을 가져오고 내보내는 방식입니다. 이 둘은 JavaScript에서 모듈을 관리하는데 중요한 차이를 갖고 있습니다.
1. CommonJS (CJS)
설명:
- Node.js에서 가장 오래 사용되어온 모듈 시스템입니다.
- 동기적(synchronous) 로드 방식을 사용하며, 서버 사이드 JavaScript에서 주로 사용됩니다.
require()
와module.exports
를 사용하여 모듈을 가져오고 내보냅니다.
문법:
- 모듈 가져오기:
require()
- 모듈 내보내기:
module.exports
예시:
// file1.js (모듈 내보내기)
module.exports = {
greet: function(name) {
return `Hello, ${name}!`;
}
};
// file2.js (모듈 가져오기)
const myModule = require('./file1');
console.log(myModule.greet('John')); // 출력: Hello, John!
특징:
- 동기적 로딩: 파일을 로드할 때 즉시 실행되며, 로딩 순서가 중요합니다.
- Node.js에서 기본적으로 사용:
require()
와module.exports
는 Node.js에서 기본적으로 제공하는 기능입니다. - 내보내는 값이 하나일 때 사용: 주로 객체, 함수, 값 하나를 내보낼 때 사용됩니다.
2. ES Modules (ESM)
설명:
- **ECMAScript 6 (ES6)**에서 표준으로 도입된 모듈 시스템입니다.
- 비동기적(asynchronous) 로드 방식을 사용합니다. 이는 브라우저 및 Node.js에서 모듈을 가져오는 표준 방식으로 사용됩니다.
import
와export
를 사용하여 모듈을 가져오고 내보냅니다.
문법:
- 모듈 가져오기:
import
- 모듈 내보내기:
export
예시:
// file1.js (모듈 내보내기)
export function greet(name) {
return `Hello, ${name}!`;
}
// file2.js (모듈 가져오기)
import { greet } from './file1.js';
console.log(greet('John')); // 출력: Hello, John!
특징:
- 비동기적 로딩: 모듈을 비동기적으로 로드하여, 파일을 병렬로 로드하고 실행합니다.
- 브라우저와 Node.js에서 사용 가능: 기본적으로 브라우저에서 사용되며, Node.js 14 이상에서는
--experimental-modules
플래그를 통해 사용 가능하고, 최신 Node.js에서는 기본적으로 지원됩니다. import
와export
로 내보내고 가져오기: 다양한 방식으로 모듈을 내보내고 가져올 수 있습니다.
3. CommonJS vs ESM 비교
특징 | CommonJS (CJS) | ES Modules (ESM) |
---|---|---|
주요 사용처 | Node.js 서버 사이드 | 브라우저, 최신 Node.js 서버 사이드 |
모듈 가져오기 | require('module') | import |
모듈 내보내기 | module.exports | export |
동기/비동기 | 동기적 (Synchronous) | 비동기적 (Asynchronous) |
기본 지원 환경 | Node.js 환경 (기본) | 브라우저, 최신 Node.js에서 기본 지원 |
로드 방식 | 동기적으로 한 번에 하나씩 로드 | 비동기적으로 여러 개를 병렬 로드 |
파일 확장자 | .js , .json , .node | .js (ESM 모드에서만) |
4. ESM의 주요 특징 (CommonJS와 다른 점)
import
와export
를 사용
ESM은 모듈을 가져오고 내보낼 때import
와export
문법을 사용합니다. 이는 표준화된 방식입니다.- 비동기적 로딩
ESM은 모듈을 비동기적으로 로드할 수 있어서, 여러 모듈을 동시에 가져오는 것이 가능해져 성능적인 장점이 있습니다. - 브라우저와 서버에서 동일한 코드 사용 가능
ESM은 브라우저와 서버에서 동일한 코드로 모듈을 사용할 수 있도록 해줍니다.import
와export
는 ES6 표준에 맞게 브라우저에서도 동작합니다. top-level await
지원
ESM에서는 최상위에서await
를 사용할 수 있습니다. 이는 비동기 처리를 훨씬 간단하게 만들어줍니다.
5. ESM 사용 시 고려사항
- Node.js 설정:
type: "module"
을package.json
에 추가해야 ESM을 사용할 수 있습니다. - 파일 확장자:
.mjs
또는.js
(type: “module”)를 사용하여 ESM을 지정할 수 있습니다. - 상위 호환성: ESM은 최신 브라우저에서 지원되며, Node.js에서도 14 이상에서 기본적으로 지원됩니다. 다만, CommonJS와 ESM은 호환성에 제한이 있으므로, 두 시스템을 혼합해서 사용할 때는 주의가 필요합니다.
🚀 결론
- ESM은 최신 표준이며 브라우저와 Node.js에서 일관되게 사용할 수 있습니다.
- CommonJS는 Node.js에서 주로 사용되며, 동기적 로딩 방식이 특징입니다.
둘 다 각각의 장점이 있으므로, 프로젝트와 환경에 맞는 모듈 시스템을 선택하는 것이 중요합니다. 최신 프로젝트는 ESM을 권장하지만, 기존 CommonJS 코드를 유지하는 경우도 많이 있습니다.