[Node.js] Module System

Main·2024년 9월 23일
0

Node.js

목록 보기
3/20
post-thumbnail

모듈 시스템은 코드를 모듈화하여 재사용성과 관리성을 높여주는 중요한 기능입니다. Node.js는 CommonJS 모듈 시스템을 기본으로 사용하며, ES6의 import/export 구문도 지원합니다.


1. CommonJS 모듈

Node.js는 CommonJS 사양을 기반으로 모듈을 정의하고 불러옵니다. 이는 대부분의 Node.js 프로젝트에서 사용되는 방식입니다.


CommonJS 특징

  • 동기 방식: require()동기적으로 모듈을 불러옵니다. 즉, 호출 시 해당 모듈이 로드될 때까지 기다린 후, 반환된 값을 사용할 수 있습니다.
  • 모듈 캐싱: require()로 불러온 모듈은 한 번만 로드되며, 이후 동일한 모듈을 다시 호출할 때는 캐싱된 값을 사용합니다.
  • 파일 확장자 생략 가능: .js 파일은 확장자를 생략할 수 있습니다. (require('./math')math.js를 자동으로 찾습니다.)

모듈 정의 (module.exports)

CommonJS 모듈 시스템에서는 exportsmodule.exports를 사용하여 모듈에서 데이터를 내보낼 수 있습니다.

  • exports는 module.exports에 대한 별칭입니다. 기본적으로 exportsmodule.exports와 같은 객체를 참조합니다. exportsmodule.exports는 같은 객체를 참조하므로 exports에 값을 직접 할당하면 안 됩니다. module.exports만 덮어쓸 수 있습니다.
  • module.exports파일 내에서 한 번만 사용할 수 있으며, 그 값은 객체, 함수, 클래스 등 하나의 값만 내보낼 수 있습니다. 이는 모듈의 최종 반환 값을 설정하는 것이기 때문에, 한 파일에서 여러 번 module.exports를 사용하면 마지막에 할당된 값만이 적용됩니다.
// math.js

exports.add = function add(a, b) {
    return a + b;
}

exports.sub = function sub(a, b) {
    return a - b;
}
// math.js

function add(a, b) {
    return a + b;
}

function sub(a, b) {
    return a - b;
}

module.exports = { 
	add, 
	sub 
};

모듈 가져오기 (require)

require 함수를 사용하여 다른 파일에서 모듈을 불러옵니다.

// app.js

const math = require('./math');
console.log(math.add(2, 3));  // 5
console.log(math.sub(3, 2));  // 1

2. ES6 모듈

ES6 모듈은 최신 JavaScript 사양에 따른 모듈 시스템으로, importexport를 사용합니다. Node.js는 12.x 버전 이후부터 실험적 지원을 시작했고, 현재는 안정적으로 사용 가능합니다.


ES6 모듈 사용하기

Node.js에서 ES6 모듈을 사용하려면 다음과 같은 방법으로 설정해야 합니다.

  • 파일 확장자: 모듈 파일 확장자로 .mjs를 사용해야 합니다.
  • package.json 설정: 또는 package.json 파일에 "type": "module"을 설정하면, .js 파일에서도 ES6 모듈 문법을 사용할 수 있습니다.
// package.json
{
  "type": "module"
}

ES6 모듈의 특징

  • 비동기 방식: ES6 모듈은 비동기적으로 로드됩니다. 브라우저 환경에서는 <script type="module">을 통해 사용할 수 있습니다.
  • 정적 분석: ES6 모듈은 파일을 로드하기 전에 어떤 모듈이 필요한지 미리 알 수 있기 때문에 정적 분석이 가능하여 최적화에 유리합니다.
  • 엄격 모드: ES6 모듈은 자동으로 엄격 모드('use strict')로 실행됩니다.

모듈 정의 (export,export default)

exportexport default는 ES6 모듈 시스템에서 모듈을 내보내는 두 가지 주요 방법입니다.

  • export는 여러 값을 모듈에서 이름을 붙여 내보낼 때 사용됩니다. 여러 개의 함수, 변수, 클래스를 내보낼 수 있으며 내보낼 때마다 각각 이름을 지정해야 합니다.
  • export default는 모듈에서 단 하나의 값을 기본으로 내보낼 때 사용됩니다. 모듈당 하나의 값만 default로 내보낼 수 있으며, 다른 파일에서 불러올 때는 이름을 자유롭게 설정할 수 있습니다.
// math.mjs

export function add(a, b) {
    return a + b;
}

export function sub(a, b) {
    return a - b;
}
// math.mjs

function add(a, b) {
    return a + b;
}

function sub(a, b) {
    return a - b;
}

export default math = {
	add,
	sub
}

모듈 가져오기 (import)

import 구문을 사용하여 ES6 모듈을 가져옵니다.

export 항목들은 다른 파일에서 해당 이름으로 가져와야 합니다. 이름을 그대로 사용해야 하며, 중괄호 { }를 사용해 가져옵니다.

// app.mjs

import { add, sub } from './math.mjs';

console.log(add(2, 3));  // 5
console.log(sub(3, 2));  // 1

import * as name 구문을 통해 전체 모듈을 가져올 수 있습니다.

// app.mjs

import * as math from './math.mjs';

console.log(math.add(2, 3));  // 5
console.log(math.sub(3, 2));  // 1

export default를 가져올 때는 중괄호 {}를 사용하지 않습니다.

// app.mjs

import math from './math.mjs';

console.log(math.add(2, 3));  // 5
console.log(math.sub(3, 2));  // 1

3. 추가 내용

CommonJS와 ES6 모듈의 호환성 문제

  • CommonJS 모듈은 동기적으로 작동하지만, ES6 모듈은 비동기적으로 작동합니다. 이를 섞어서 사용할 때 주의해야 합니다.
  • Node.js에서 ES6 모듈과 CommonJS 모듈을 함께 사용할 경우, require()import를 함께 사용할 수 있지만 호환성 이슈가 발생할 수 있습니다. 예를 들어:
    • ES6 모듈에서 CommonJS 모듈을 가져올 때는 기본 내보내기(module.exports)만을 사용할 수 있습니다.
    • CommonJS 모듈에서 ES6 모듈을 가져올 때는 비동기 방식으로 작동하기 때문에 import()로 동적으로 불러와야 할 수 있습니다.

ES6 모듈의 비동기 로드

CommonJS는 동기적으로 모듈을 로드하는 반면, ES6 모듈은 비동기적으로 로드될 수 있습니다. 브라우저 환경에서는 ES6 모듈이 기본적으로 비동기적으로 처리되며, type="module"로 스크립트를 선언해야 합니다.

<script type="module" src="app.mjs"></script>

동적 import

  • ES6 모듈에서 import()동적으로 모듈을 불러올 수 있는 함수입니다. 이 기능을 사용하면 필요할 때 모듈을 불러올 수 있어 성능 최적화에 도움이 될 수 있습니다.
    // 동적 import 예시
    async function loadMathModule() {
        const math = await import('./math.mjs');
        console.log(math.add(2, 3));  // 5
    }
profile
함께 개선하는 프론트엔드 개발자

0개의 댓글