모듈이란, 거대한 코드 뭉치를 여러 파일로 분리하여 관리할 수 있게 해주는 기능입니다. 파일을 분리하게 되면 각 파일은 특정 기능을 갖는 작은 코드 단위가 되어 재사용성, 유지 및 관리, 네임스페이스 관리 등의 장점을 가집니다.
모듈 시스템은 JavaScript에서 코드를 구조화하는 방법 중 하나입니다.
JavaScript에서 사용되는 두 가지 주요 모듈 시스템은 CommonJs(CJS)
와 ES Module(ESM)
으로 나뉩니다. 각각의 시스템은 모듈을 정의하고, 사용하는 방식에서 차이를 보입니다.
CommonJS는 주로 Node.js에서 사용되는 모듈 시스템입니다. 파일 하나가 모듈 하나로 간주됩니다. CommonJS 모듈은 require
함수를 사용해 다른 모듈을 불러오고, module.exports
또는 exports
객체를 사용해 모듈의 내용을 외부에 노출합니다.
// math.js
function add(x, y) {
return x + y;
}
module.exports = { add };
// app.js
const math = require('./math.js');
console.log(math.add(2, 3)); // 출력: 5
ES Module은 ECMAScript (JavaScript의 공식 명칭) 표준의 일부로, 웹에서 사용되는 모듈 시스템입니다. export
와 import
구문을 사용하여 모듈을 불러오고 내보냅니다. export 구문은 모듈에서 함수, 객체, 변수 등을 외부로 내보내고 싶을 때 사용하고, import 구문은 다른 모듈에서 내보낸 것들을 가져오고 싶을 때 사용합니다.
// 두 수를 더하는 함수를 export 합니다.
export function add(x, y) {
return x + y;
}
// math.js 모듈에서 add 함수를 import 합니다.
import { add } from './math.js';
console.log(add(2, 3)); // 출력: 5
주요 차이점
정의와 사용
: CommonJS는 require와 module.exports를, ESM은 import와 export를 사용합니다.
로딩 메커니즘
: CommonJS 모듈은 동기적으로 로딩되는 반면, ESM은 비동기적 로딩이 가능합니다. 이는 웹에서 모듈을 효율적으로 불러올 수 있게 해줍니다. 브라우저는 import문을 통해서 동적 로딩이 가능하게됩니다.
사용 환경
: CommonJS는 주로 Node.js 환경에서 사용되고, ESM은 최신 웹 브라우저와 Node.js 환경 모두에서 사용됩니다.
최적화
: ESM은 정적 구조를 가지고 있어, 빌드 타임에 모듈 구조가 결정됩니다. 이러한 특성 덕분에 코드 분석과 불필요한 코드 제거(트리 쉐이킹) 같은 최적화 작업이 가능합니다.
각 모듈 시스템은 사용 환경과 요구 사항에 따라 선택할 수 있으며, 현대의 JavaScript 개발 환경에서는 점점 ESM이 선호되는 추세입니다. 추세에 맞게 모듈 번들러도 webpack에서 vite로 넘어가고 있습니다.
모듈 시스템이 CommonJS와 ES 모듈로 나뉜 이유는?
자바스크립트의 사용 환경과 그에 따른 요구 사항이 시간에 따라 변화했기 때문입니다. 각 시스템은 자바스크립트가 사용되는 다양한 컨텍스트와 요구에 맞춰 발전해 왔습니다.
CommonJS는 주로 서버 사이드에서 사용하기 위해 설계된 모듈 시스템입니다. Node.js의 초기 버전에서 사용되기 시작한 이 모듈 시스템은 자바스크립트가 웹 브라우저 외부, 특히 서버 사이드 애플리케이션에서 널리 사용될 수 있도록 만들어졌습니다.
ES 모듈은 ECMAScript(ES) 표준의 일부로, 브라우저와 서버 모두에서 사용될 수 있는 표준화된 모듈 시스템을 제공하기 위해 도입되었습니다. 이 시스템은 웹 애플리케이션의 복잡성 증가와 함께 모듈화된 접근 방식이 필요하게 되면서 생겨났습니다.
따라서 자바스크립트가 웹 브라우저에서 뿐만 아니라 서버, 데스크탑 애플리케이션, 모바일 애플리케이션 등 다양한 환경에서 사용되면서 각 환경에 맞는 요구 사항을 충족시키기 위해 발전했습니다.
자바스크립트의 급속한 성장과 함께 개발 커뮤니티는 코드의 재사용성과 이식성을 향상시키기 위해 표준화된 모듈 시스템의 필요성을 느꼈습니다. ES 모듈은 이러한 요구를 반영하여 표준화된 접근 방식을 제공합니다. 웹 애플리케이션의 성능 최적화를 위해 모듈 로딩과 실행을 더 세밀하게 제어할 수 있는 시스템이 필요했습니다. ES 모듈은 이러한 요구에 부응하는 기능들을 제공합니다.
이러한 배경과 특성 때문에 현재 두 모듈 시스템이 공존하며, 각각의 장점을 살려 다양한 환경과 요구 사항에 따라 적절히 사용되고 있습니다.
모듈 번들러는 여러 개의 파일(모듈)을 하나 또는 여러 개의 파일로 결합(번들링)하는 도구입니다. 모듈 번들러는 개발 과정을 효율화하고, 웹 애플리케이션의 로딩 시간을 줄이는 데 도움을 줍니다. 대표적인 모듈 번들러로는 Webpack, Rollup, vite, esbuild, Parcel 등이 있습니다.
번들링
: 여러 모듈과 파일을 하나 또는 여러 개의 파일로 합쳐서 브라우저에서 빠르게 로드할 수 있도록 합니다.
로더와 플러그인 시스템
: JavaScript 이외의 리소스(예: CSS, 이미지, HTML)를 모듈처럼 처리할 수 있게 해주는 로더와, 번들링 과정을 사용자가 정의할 수 있도록 해주는 플러그인 시스템을 제공합니다.
코드 변환
: 최신 JavaScript 문법(ES6 이상)을 모든 브라우저에서 호환 가능한 형태로 변환하거나, TypeScript나 JSX 같은 언어를 JavaScript로 변환합니다.
트리쉐이킹
: 코드를 압축하고, 불필요한 코드를 제거하는 트리 쉐이킹(Tree Shaking) 등의 최적화 작업을 수행합니다.