자바스크립트 모듈 시스템: CommonJS, AMD, CMD, ES6

CommonJS

CommonJS는 서버 측에서 동기 방식으로 모듈을 로드하는 방식입니다. 로컬 디스크에 저장된 모듈 파일들은 매우 빠르게 접근할 수 있기 때문에 성능 문제는 없습니다. 하지만 브라우저 환경에서는 네트워크 지연을 고려해 비동기 방식이 더 적합합니다. 모듈의 인터페이스를 정의하기 위해 module.exports를 사용하고, 다른 모듈을 불러오기 위해서는 require를 사용합니다.

// myMath.js 모듈 정의
let initialNumber = 0;
function sum(a, b) {
  return a + b;
}
module.exports = { sum, initialNumber };

// 다른 모듈에서 참조
const math = require('./myMath');
console.log(math.sum(10, 5));

// 내장 모듈 참조 예시
const http = require('http');
http.createServer(...).listen(3000);

AMD (Asynchronous Module Definition)

AMD는 비동기적으로 모듈을 로드하는 스펙으로, 의존성 관리를 콜백 함수 내부에서 처리합니다. 주로 definerequire 메서드를 사용하며, 대표적인 구현체는 RequireJS입니다.

// math 모듈 정의
define(function () {
    let startValue = 0;
    function calculate(x, y) {
        return x + y;
    }
    return { calculate, startValue };
});

// 의존성 있는 모듈 정의
define(['lodash'], function (_) {
    function categorize(list) {
        _.countBy(list, (num) => (num > 30 ? 'old' : 'young'));
    }
    return { categorize };
});

// 모듈 참조 및 사용
require(['jquery', 'math'], function ($, math) {
    const total = math.calculate(10, 20);
    $('#total').html(total);
});

CMD (Common Module Definition)

CMD는 의존성을 가까운 위치에서 선언하며, 실행은 필요할 때만 이루어집니다. Sea.js가 대표적인 구현체입니다.

// AMD 스타일
define(["a", "b"], function (a, b) {
    a.doSomething();
    if (false) {
        b.doSomething(); // 미사용된 모듈도 초기화됨
    }
});

// CMD 스타일
define(function (require, exports, module) {
    const a = require('./a'); // 필요할 때만 호출
    a.doSomething();
    if (false) {
        const b = require('./b');
        b.doSomething(); // 실제로 사용되지 않으면 로드하지 않음
    }
});

ES6 모듈

ES6 모듈 시스템은 명확한 모듈 경계를 제공하며, exportimport를 통해 모듈 간 상호작용을 지원합니다. 이 방식은 코드가 실행되기 전에 정적 분석 단계에서 수행되므로 조건부 로딩은 불가능합니다.

// calculator.js 모듈 정의
let baseValue = 0;
function compute(a, b) {
    return a + b;
}
export { baseValue, compute };

// 모듈 참조
import { baseValue, compute } from './calculator';
function displayResult(element) {
    element.textContent = compute(99, baseValue);
}

ES6 모듈과 CommonJS 모듈의 차이점

1. **값의 복사 vs 참조**: CommonJS는 값의 복사를 통해 모듈을 내보내며, 이후 모듈 내부 상태의 변화는 반영되지 않습니다. 반면 ES6 모듈은 값의 참조를 내보내기 때문에 원본 데이터의 변경 사항이 자동으로 반영됩니다. 2. **실행 시 로딩 vs 컴파일 시 로딩**: CommonJS는 스크립트가 실행되는 동안 모듈을 로드하는 동적 방식이며, 전체 모듈 객체를 메모리에 올립니다. 그러나 ES6 모듈은 코드가 실행되기 전에 정적으로 분석되어 필요한 부분만 선택적으로 로드됩니다. 따라서 ES6 모듈은 보다 효율적이고 최적화된 로딩이 가능합니다.

태그: JavaScript modules ES6

8월 3일 03:17에 게시됨