728x90
반응형
1. 모듈 시스템이란
모듈 시스템은 코드를 여러 파일로 분리하고 재사용할 수 있게 해주는 구조입니다. Node.js는 CommonJS와 ES Modules 두 가지 모듈 시스템을 지원합니다. 모듈화를 통해 코드의 유지보수성, 재사용성, 캡슐화를 향상시킬 수 있습니다.
2. CommonJS (CJS)
Node.js의 기본 모듈 시스템으로, require()와 module.exports를 사용합니다.
2.1 모듈 내보내기
// math.js
// 방법 1: module.exports에 객체 할당
module.exports = {
add: (a, b) => a + b,
subtract: (a, b) => a - b
};
// 방법 2: exports에 속성 추가
exports.multiply = (a, b) => a * b;
exports.divide = (a, b) => a / b;
// 방법 3: 단일 함수/클래스 내보내기
module.exports = function Calculator() {
this.value = 0;
};
2.2 모듈 가져오기
// app.js
// 전체 모듈 가져오기
const math = require('./math');
console.log(math.add(2, 3)); // 5
// 구조 분해 할당으로 가져오기
const { add, subtract } = require('./math');
console.log(add(2, 3)); // 5
// 내장 모듈 가져오기
const fs = require('fs');
const path = require('path');
// npm 패키지 가져오기
const express = require('express');
2.3 module.exports vs exports
// exports는 module.exports의 참조
console.log(exports === module.exports); // true
// exports에 직접 할당하면 참조가 끊어짐 (작동 안 함)
exports = { name: 'test' }; // 잘못된 방법
// module.exports에 할당해야 함
module.exports = { name: 'test' }; // 올바른 방법
3. ES Modules (ESM)
ES6에서 도입된 표준 JavaScript 모듈 시스템입니다. Node.js 12버전부터 안정적으로 지원됩니다.
3.1 ESM 활성화 방법
// package.json
{
"type": "module"
}
또는 파일 확장자를 .mjs로 사용합니다.
3.2 모듈 내보내기
// utils.mjs 또는 utils.js (type: module 설정 시)
// Named Export (이름 있는 내보내기)
export const PI = 3.14159;
export function add(a, b) {
return a + b;
}
export class Calculator {
constructor() {
this.value = 0;
}
}
// Default Export (기본 내보내기)
export default function main() {
console.log('메인 함수');
}
3.3 모듈 가져오기
// app.mjs
// Named Import
import { add, PI } from './utils.mjs';
// Default Import
import main from './utils.mjs';
// 모든 것을 객체로 가져오기
import * as utils from './utils.mjs';
console.log(utils.add(2, 3));
// Named + Default 함께 가져오기
import main, { add, PI } from './utils.mjs';
// 이름 변경하여 가져오기
import { add as sum } from './utils.mjs';
반응형
4. CommonJS vs ES Modules 비교
| 특성 | CommonJS | ES Modules |
|---|---|---|
| 문법 | require() / module.exports | import / export |
| 로딩 | 동기적 | 비동기적 |
| 파일 확장자 | .js, .cjs | .mjs 또는 type: module |
| Top-level await | 불가능 | 가능 |
| this | module.exports | undefined |
| 동적 import | require() 어디서든 가능 | import() 사용 |
5. 동적 Import
5.1 CommonJS 동적 로딩
// 조건부 로딩
if (condition) {
const module = require('./moduleA');
} else {
const module = require('./moduleB');
}
5.2 ESM 동적 로딩
// import()는 프로미스를 반환
async function loadModule() {
if (condition) {
const module = await import('./moduleA.mjs');
module.default();
}
}
// Top-level await (ESM에서만 가능)
const config = await import('./config.mjs');
6. 내장 모듈 vs 외부 모듈
6.1 내장 모듈
Node.js에 기본으로 포함된 모듈입니다.
// CommonJS
const fs = require('fs');
const path = require('path');
const http = require('http');
const crypto = require('crypto');
// ESM
import fs from 'fs';
import path from 'path';
// 또는 node: 프로토콜 사용 (권장)
import fs from 'node:fs';
import path from 'node:path';
6.2 외부 모듈 (npm 패키지)
npm을 통해 설치한 모듈입니다.
// 설치
// npm install express lodash
// 사용
const express = require('express');
import _ from 'lodash';
7. 모듈 캐싱
Node.js는 모듈을 한 번 로드하면 캐시에 저장합니다.
// moduleA.js
console.log('모듈 A 로드됨');
module.exports = { value: 1 };
// app.js
const a1 = require('./moduleA'); // '모듈 A 로드됨' 출력
const a2 = require('./moduleA'); // 출력 없음 (캐시에서 로드)
console.log(a1 === a2); // true
// 캐시 확인
console.log(require.cache);
// 캐시 삭제 (재로드 필요시)
delete require.cache[require.resolve('./moduleA')];
8. 순환 참조 처리
// a.js
console.log('a.js 시작');
exports.done = false;
const b = require('./b');
console.log('b.done:', b.done);
exports.done = true;
console.log('a.js 완료');
// b.js
console.log('b.js 시작');
exports.done = false;
const a = require('./a');
console.log('a.done:', a.done); // false (a.js가 아직 완료되지 않음)
exports.done = true;
console.log('b.js 완료');
// main.js
require('./a');
// 출력:
// a.js 시작
// b.js 시작
// a.done: false
// b.js 완료
// b.done: true
// a.js 완료
순환 참조는 가능하면 피하는 것이 좋습니다. 코드 구조를 재설계하거나 의존성 주입 패턴을 사용하세요.
결론
Node.js는 CommonJS와 ES Modules 두 가지 모듈 시스템을 지원합니다. CommonJS는 require/module.exports를 사용하고, ES Modules는 import/export를 사용합니다. 새 프로젝트에서는 ES Modules 사용이 권장되며, 기존 프로젝트와의 호환성이 필요하면 CommonJS를 사용합니다. 모듈 캐싱과 순환 참조에 대한 이해도 중요합니다.
728x90
반응형
'Node.js' 카테고리의 다른 글
| Node.js의 async/await 사용법 (0) | 2026.02.22 |
|---|---|
| Node.js의 프로미스(Promise) 사용법 (0) | 2026.02.22 |
| Node.js의 콜백 함수(Callback Functions) (0) | 2026.02.22 |
| Node.js의 비동기 프로그래밍(Asynchronous Programming) (0) | 2026.02.21 |
| Node.js의 이벤트 루프(Event Loop) (0) | 2026.02.21 |