반응형
CommonJS와 ESM(ECMAScript Modules)은 JavaScript에서 모듈을 정의하고 불러오는 두 가지 주요 방식입니다. 두 모듈 시스템 모두 파일 간의 코드를 분리하고 재사용하는 방법을 제공하지만, 그 방식과 동작 원리에서 큰 차이가 있습니다. 아래에서는 CommonJS와 ESM의 주요 차이점을 설명합니다.
1. 역사적 배경
CommonJS
- 개발 시기: CommonJS는 Node.js에서 사용하기 위해 만들어졌습니다. 브라우저 환경에서는 기본적으로 사용되지 않으며, Node.js의 초기 버전에서 모듈 시스템으로 채택되었습니다.
- 목적: 서버 사이드 JavaScript의 모듈화를 위해 도입되었습니다.
- 채택: Node.js가 처음 등장했을 때부터 기본 모듈 시스템으로 사용되어 왔으며, 현재도 대부분의 Node.js 프로젝트에서 널리 사용됩니다.
ECMAScript Modules (ESM)
- 개발 시기: ESM은 JavaScript 표준화 위원회(ECMA)가 공식적으로 정의한 모듈 시스템입니다.
ES6
(ECMAScript 2015)에서 도입되었습니다. - 목적: 브라우저와 서버 환경 모두에서 통일된 모듈 시스템을 제공하기 위해 도입되었습니다.
- 채택: ESM은 최신 브라우저와 Node.js 12 이상에서 지원됩니다. ESM은 JavaScript의 표준 모듈 시스템입니다.
2. 문법 차이
CommonJS (Node.js에서 사용)
- 모듈 불러오기:
require()
함수로 모듈을 불러옵니다. - 모듈 내보내기:
module.exports
또는exports
객체를 사용해 모듈을 내보냅니다.
// 불러오기 (CommonJS)
const myModule = require('./myModule');
// 내보내기 (CommonJS)
module.exports = {
myFunction: function() { ... }
};
ESM (ECMAScript 모듈)
- 모듈 불러오기:
import
키워드를 사용해 모듈을 불러옵니다. - 모듈 내보내기:
export
또는export default
를 사용해 모듈을 내보냅니다.
// 불러오기 (ESM)
import myModule from './myModule.js';
// 내보내기 (ESM)
export default function myFunction() { ... };
export const myVariable = 42;
주요 차이점
require()
vsimport
: CommonJS는 함수 형태인require()
로 모듈을 동적으로 불러오고, ESM은import
를 사용해 정적으로 모듈을 불러옵니다.- 동적 로딩: CommonJS는 동적으로 모듈을 불러오는 것이 가능하지만, ESM은 기본적으로 정적 분석이 요구됩니다. 다만, ESM에서도
import()
함수로 동적 로딩이 가능합니다.
3. 모듈 내보내기 방식
CommonJS
- CommonJS에서는
module.exports
객체를 사용해 모듈을 내보냅니다. 이는 기본적으로 하나의 객체를 내보내는 방식입니다.
// 내보내기
module.exports = {
myFunction: function() { ... }
};
- 여러 객체를 내보낼 때
exports
객체를 사용해 개별 속성으로 내보낼 수 있습니다.
exports.myFunction = function() { ... };
exports.myVariable = 42;
ESM
- ESM에서는
export
와export default
를 사용합니다.export
는 여러 개의 개별적인 변수나 함수를 내보낼 수 있습니다.
// 여러 개 내보내기
export const myFunction = () => { ... };
export const myVariable = 42;
export default
는 파일당 단일 기본 모듈을 내보낼 수 있도록 설계되었습니다.
// 기본 내보내기
export default function myFunction() { ... };
4. 로딩 방식
CommonJS: 동기적 로딩
require()
는 동기적으로 동작하며, 모듈이 로드될 때까지 코드 실행이 중단됩니다.- Node.js에서는 이 방식이 서버 사이드 환경에서 성능 문제를 일으키지 않지만, 브라우저 환경에서는 적합하지 않을 수 있습니다.
ESM: 비동기적 로딩
- ESM은 비동기적으로 모듈을 로드합니다. 특히, 브라우저 환경에서 비동기 로딩이 필수적이기 때문에 ESM은 기본적으로 비동기 방식으로 동작합니다.
- ESM은 JavaScript 엔진이 컴파일 타임에 모듈을 분석하여 필요한 모듈을 미리 가져오기 때문에, 최적화에 유리합니다.
5. 동적 로딩 지원
CommonJS
- CommonJS는
require()
자체가 함수이기 때문에 동적으로 모듈을 불러오는 것이 매우 쉽습니다. 조건문 안에서require()
를 사용해 특정 상황에서만 모듈을 불러오는 것이 가능합니다.
if (condition) {
const myModule = require('./myModule');
}
ESM
- ESM의
import
는 정적 분석이 필요하기 때문에 기본적으로 파일 최상단에서 사용해야 하며, 동적 로딩이 불가능합니다. - 그러나, ES2020부터 도입된 동적
import()
문법을 사용하면 ESM에서도 모듈을 동적으로 로딩할 수 있습니다. 이 방식은 Promise를 반환합니다.
// 동적 import
import('./myModule.js').then(module => {
module.myFunction();
});
6. 트리 셰이킹(Tree Shaking)
CommonJS
- CommonJS는 런타임에
require()
로 모듈을 불러오기 때문에 트리 셰이킹(필요 없는 코드를 제거하는 최적화 기법)이 불가능합니다. 모든 모듈을 불러온 후, 사용되지 않더라도 포함됩니다.
ESM
- ESM은 정적 분석을 기반으로 하므로 트리 셰이킹이 가능합니다. 코드 번들러(Webpack, Rollup 등)는 사용되지 않은 모듈을 컴파일 단계에서 제거할 수 있어 최적화된 번들 크기를 제공합니다.
7. 호환성 및 파일 확장자
CommonJS
- Node.js는 CommonJS를 기본 모듈 시스템으로 사용하며, 모든 Node.js 버전에서 기본적으로 지원됩니다.
- CommonJS 파일은 일반적으로
.js
확장자를 사용합니다.
ESM
- Node.js 12+ 버전에서 ESM이 도입되었으며, Node.js에서 사용하려면 두 가지 방법 중 하나를 따라야 합니다:
- 파일 확장자를
.mjs
로 사용. package.json
파일에서"type": "module"
을 설정.
- 파일 확장자를
- 브라우저 환경에서도 ESM이 기본적으로 지원되며,
<script type="module">
태그를 사용해 ESM을 로드할 수 있습니다.
<script type="module">
import myModule from './myModule.js';
</script>
8. 요약 비교
특징 | CommonJS | ESM (ECMAScript Modules) |
사용 환경 | Node.js | Node.js, 브라우저 |
모듈 불러오기 | require() | import |
모듈 내보내기 | module.exports, exports | export, export default |
로딩 방식 | 동기적 | 비동기적 |
동적 로딩 | 가능 (require()로 동적 로딩) | 가능 (import()로 비동기 로딩) |
트리 셰이킹 지원 | 불가능 | 가능 |
파일 확장자 | .js | .mjs 또는 "type": "module" |
호환성 | 모든 Node.js 버전 | Node.js 12+, 브라우저 |
9. 결론
- CommonJS는 Node.js 환경에서 오래된 모듈 시스템이며, 대부분의 기존 Node.js 프로젝트에서 여전히 사용되고 있습니다.
- ESM은 최신 JavaScript 표준 모듈 시스템으로, 브라우저와 Node.js 모두에서 통일된 방식으로 사용됩니다. ESM은 더 많은 최적화 가능성을 제공하며, 특히 트리 셰이킹과 같은 최적화 기법을 지원하는 점에서 유리합니다.
반응형
'언어 > Node.js' 카테고리의 다른 글
[ Node.js ] unzipper로 압축 파일 풀기 (1) | 2024.09.05 |
---|---|
[ Node.js ] require() vs import 비교 (0) | 2024.09.04 |
[ Node.js ] Node.js 버전 역사. (0) | 2024.09.04 |
[ Node.js ] 간단한 웹 스파이더 작성하기 (0) | 2024.06.16 |
[ Node.js ] 비동기 함수 EventEmitter 사용하기 (0) | 2024.06.16 |