ESM과 CJS의 차이점과 노드 환경에서의 설정 방법
F-Lab : 상위 1% 개발자들의 멘토링
AI가 제공하는 얕고 넓은 지식을 위한 짤막한 글입니다!

ESM과 CJS의 개요
JavaScript 모듈 시스템은 크게 ESM(ECMAScript Modules)과 CJS(CommonJS)로 나뉩니다. ESM은 최신 JavaScript 표준에 기반한 모듈 시스템으로, 브라우저와 Node.js에서 모두 사용할 수 있습니다. 반면, CJS는 Node.js에서 주로 사용되던 기존의 모듈 시스템입니다.
ESM은 import
와 export
키워드를 사용하여 모듈을 정의하고 가져옵니다. 반면, CJS는 require
와 module.exports
를 사용합니다. 두 시스템은 서로 호환되지 않기 때문에, 프로젝트에서 하나를 선택하여 사용하는 것이 중요합니다.
왜냐하면 ESM은 브라우저와 Node.js 모두에서 사용 가능하며, 최신 JavaScript 표준을 따르기 때문에 코드의 이식성과 유지보수성이 높아지기 때문입니다.
Node.js는 기본적으로 CJS를 지원하지만, ESM을 사용하려면 몇 가지 설정이 필요합니다. 이 글에서는 ESM과 CJS의 차이점과 함께, Node.js에서 ESM을 설정하는 방법을 알아보겠습니다.
이러한 설정은 특히 모듈화된 프로젝트를 개발하거나, 최신 JavaScript 기능을 활용하려는 개발자들에게 매우 유용합니다.
ESM과 CJS의 주요 차이점
ESM과 CJS의 가장 큰 차이점은 모듈을 가져오고 내보내는 방식입니다. ESM은 정적 구조를 가지며, import
와 export
를 사용합니다. 반면, CJS는 동적 구조를 가지며, require
와 module.exports
를 사용합니다.
ESM은 정적 분석이 가능하기 때문에, 트리 쉐이킹(tree-shaking)과 같은 최적화 기법을 사용할 수 있습니다. 반면, CJS는 동적 로딩을 지원하지만, 정적 분석이 어렵습니다.
왜냐하면 ESM은 컴파일 타임에 모듈 의존성을 분석할 수 있는 반면, CJS는 런타임에 의존성을 분석하기 때문입니다.
또한, ESM은 비동기적으로 모듈을 로드할 수 있는 반면, CJS는 동기적으로 로드됩니다. 이는 ESM이 브라우저 환경에서 더 적합한 이유 중 하나입니다.
Node.js에서 ESM을 사용하려면, package.json
파일에 "type": "module"
을 추가해야 합니다. 반면, CJS는 기본적으로 지원되므로 별도의 설정이 필요하지 않습니다.
Node.js에서 ESM 설정하기
Node.js에서 ESM을 사용하려면 몇 가지 설정이 필요합니다. 첫 번째로, package.json
파일에 "type": "module"
을 추가해야 합니다. 이 설정은 프로젝트 전체에서 ESM을 활성화합니다.
두 번째로, ESM 모듈을 가져올 때 파일 확장자를 명시해야 합니다. 예를 들어, import myModule from './myModule.js';
와 같이 작성해야 합니다.
왜냐하면 Node.js는 기본적으로 CJS를 사용하며, ESM을 활성화하려면 명시적인 설정이 필요하기 때문입니다.
세 번째로, ESM과 CJS를 혼합하여 사용할 경우, require
와 import
를 적절히 분리해야 합니다. 이는 코드의 일관성을 유지하고, 예기치 않은 오류를 방지하기 위함입니다.
아래는 ESM 설정의 예제 코드입니다:
{ "type": "module" }
이 설정을 통해 Node.js에서 ESM을 사용할 수 있습니다.
ESM과 CJS 혼합 사용 시 주의사항
ESM과 CJS를 혼합하여 사용할 경우, 몇 가지 주의사항이 있습니다. 첫 번째로, ESM 모듈에서 CJS 모듈을 가져올 때는 createRequire
를 사용해야 합니다. 이는 Node.js에서 제공하는 유틸리티 함수입니다.
두 번째로, CJS 모듈에서 ESM 모듈을 가져올 때는 동적 import()
를 사용해야 합니다. 이는 비동기적으로 동작하며, Promise를 반환합니다.
왜냐하면 ESM과 CJS는 서로 다른 모듈 시스템을 사용하며, 직접적으로 호환되지 않기 때문입니다.
세 번째로, 혼합 사용 시 코드의 복잡성이 증가할 수 있으므로, 가능하면 하나의 모듈 시스템을 사용하는 것이 좋습니다. 이는 코드의 가독성과 유지보수성을 높이는 데 도움이 됩니다.
아래는 ESM과 CJS를 혼합 사용하는 예제 코드입니다:
// ESM에서 CJS 모듈 가져오기 import { createRequire } from 'module'; const require = createRequire(import.meta.url); const myModule = require('./myModule.cjs'); // CJS에서 ESM 모듈 가져오기 (async () => { const myModule = await import('./myModule.js'); })();
결론 및 추천
ESM과 CJS는 각각의 장단점이 있으며, 프로젝트의 요구사항에 따라 적절히 선택해야 합니다. ESM은 최신 JavaScript 표준을 따르며, 브라우저와 Node.js 모두에서 사용할 수 있습니다. 반면, CJS는 Node.js에서 기본적으로 지원되며, 기존 프로젝트와의 호환성이 뛰어납니다.
Node.js에서 ESM을 사용하려면, package.json
파일에 "type": "module"
을 추가하고, 파일 확장자를 명시해야 합니다. 또한, ESM과 CJS를 혼합하여 사용할 경우, createRequire
와 동적 import()
를 적절히 활용해야 합니다.
왜냐하면 이러한 설정과 주의사항을 준수함으로써, 모듈 시스템 간의 호환성을 유지하고, 예기치 않은 오류를 방지할 수 있기 때문입니다.
결론적으로, 새로운 프로젝트에서는 ESM을 사용하는 것이 권장되며, 기존 프로젝트에서는 CJS를 유지하거나, 점진적으로 ESM으로 전환하는 것이 좋습니다.
이 글이 ESM과 CJS의 차이점을 이해하고, Node.js에서 ESM을 설정하는 데 도움이 되길 바랍니다.
이 컨텐츠는 F-Lab의 고유 자산으로 상업적인 목적의 복사 및 배포를 금합니다.