[Node.js] 모듈 시스템 (CJS vs ES Module)

2025. 11. 12. 20:20·React/Node.js

모듈이 뭐임?

모듈은 쉽게 말해서 레고 블록 같은 것

프로그램을 만들 때 모든 코드를 한 파일에 다 때려 넣으면 너무 복잡하고 관리하기 어려움.

그래서 기능별로 코드를 나눠서 다른 파일로 만들고, 필요할 때 가져다 쓰는 것

예를 들어:

  • `math.js` → 수학 계산 기능
  • `user.js` → 사용자 관리 기능
  • `database.js` → 데이터베이스 연결 기능

이렇게 나눠두면 재사용도 쉽고, 유지보수도 편함!


Node.js의 두 가지 모듈 시스템

Node.js에는 모듈을 사용하는 방법이 2가지 있음:

구분 CommonJS (CJS) ES Module (ESM)
사용 키워드 `require` / `module.exports` `import` / `export`
등장 시기 Node.js 초기부터 최신 JavaScript 표준
파일 확장자 `.js` (기본) `.mjs` 또는 `.js` (package.json 설정 필요)
로딩 방식 동기(Synchronous) 비동기(Asynchronous)
브라우저 지원 (Node.js 전용) (최신 브라우저 지원)

1. 모듈 만들기 (Export)

`math.js` 파일

먼저 수학 계산 기능을 모아둔 모듈을 만들어보겠음

 

1. CommonJS 방식 (구식이지만 아직 많이 씀)

// 덧셈 함수
function add(a, b) {
  return a + b;
}

// 뺄셈 함수
function sub(a, b) {
  return a - b;
}

// CommonJS 방식으로 내보내기
module.exports = {
  add,  // 키와 값이 같으면 하나만 써도 됨 (add: add 와 동일)
  sub,
};

설명

  • `module.exports`는 "이 파일에서 이것들을 내보낼게!"라고 선언하는 것
  • 객체 형태로 여러 함수를 한 번에 내보낼 수 있음
  • 키와 변수명이 같으면 생략 가능 (ES6 단축 속성)

2. ES Module 방식 (최신 방식, 요즘 트렌드!)

// 방법 1: 함수 정의 후 한번에 export
function add(a, b) {
  return a + b;
}

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

export { add, sub };
// 방법 2: 함수 정의할 때 바로 export (더 간단!)
export function add(a, b) {
  return a + b;
}

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

설명

  • `export` 키워드로 함수를 내보냄
  • 함수 선언 앞에 바로 붙이거나, 나중에 한꺼번에 내보낼 수 있음
  • 각각의 함수를 Named Export(이름이 있는 내보내기)라고 부름

3. Default Export (대표 선수 정하기)

// 이 모듈의 대표 함수 (곱셈)
export default function multiply(a, b) {
  return a * b;
}

설명:

  • `default`는 "이 모듈의 대표 기능이야!"라고 지정하는 것
  • 파일당 딱 1개만 가능
  • 가져올 때 이름을 마음대로 바꿀 수 있음

4. 다양한 것들 내보내기

// 나눗셈 함수
export function divide(a, b) {
  if (b === 0) {
    return "0으로 나눌 수 없습니다";
  }
  return a / b;
}

// 거듭제곱 함수
export function power(a, b) {
  return Math.pow(a, b);
}

// 상수도 export 가능!
export const PI = 3.14159;

설명

  • 함수뿐만 아니라 변수, 상수, 클래스 등 뭐든지 내보낼 수 있음
  • `const`, `let`, `var` 앞에 `export`를 붙이면 됨

2. 모듈 가져다 쓰기 (Import)

`index.js` 파일

이제 만들어둔 모듈을 가져와서 사용해볼 것

 

1. CommonJS 방식으로 가져오기

// 방법 1: 전체를 객체로 받기
const moduleData = require("./math");

console.log(moduleData.add(1, 2));  // 3
console.log(moduleData.sub(1, 2));  // -1
 
// 방법 2: 구조 분해 할당으로 필요한 것만 받기 (더 깔끔!)
const { add, sub } = require("./math");

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

설명

  • `require()`로 다른 파일의 모듈을 가져옴
  • 구조 분해 할당을 쓰면 필요한 함수만 꺼내 쓸 수 있음
  • ./는 "현재 폴더"를 의미함

2. ES Module 기본 import

// Default export 가져오기
import multiply from "./math.js";

// Named export 가져오기
import { add, sub } from "./math.js";

console.log("=== 기본 import ===");
console.log(add(1, 2));        // 3
console.log(sub(1, 2));        // -1
console.log(multiply(3, 4));   // 12

설명

  • ES Module에서는 `.js` 확장자를 반드시 써야 함
  • Default export는 `{}`없이 가져오고, Named export는 `{}`로 감싸서 가져옴
  • 한 줄에 여러 개를 import할 수 있음

3. 별칭(Alias) 사용하기

import { add as plus, sub as minus } from "./math.js";

console.log("\n=== 별칭 사용 ===");
console.log(plus(5, 3));   // 8
console.log(minus(5, 3));  // 2

설명

  • `as` 키워드로 가져올 때 이름을 바꿀 수 있음
  • 이름이 겹치거나, 더 직관적인 이름을 쓰고 싶을 때 유용함
  • `add`를 `plus`라는 이름으로 사용 가능

4. 전체 import (와일드카드)

import * as math from "./math.js";

console.log("\n=== 전체 import (*) ===");
console.log(math.add(10, 5));      // 15
console.log(math.sub(10, 5));      // 5
console.log(math.default(2, 6));   // 12 (default export는 .default로 접근)

설명

  • `* as 이름` 형태로 모든 export를 한 번에 가져올 수 있음
  • 모든 함수가 `math` 객체의 속성이 됨
  • Default export는 `.default`로 접근해야 함 (주의!)

5. 추가 함수들 사용하기

import { divide, power, PI } from "./math.js";

console.log("\n=== 추가 함수들 ===");
console.log(divide(10, 2));   // 5
console.log(divide(10, 0));   // "0으로 나눌 수 없습니다"
console.log(power(2, 3));     // 8
console.log(PI);              // 3.14159

설명:

  • 필요한 것만 골라서 가져올 수 있음
  • 상수(`PI`)도 똑같이 import 가능
  • 에러 처리가 되어있는 함수는 안전하게 사용 가능

 

6. Default + Named Export 동시에 가져오기

import multiply2, { add as addition, divide as div } from "./math.js";

console.log("\n=== Default + Named 동시 import ===");
console.log(multiply2(4, 5));    // 20
console.log(addition(100, 200)); // 300
console.log(div(20, 4));         // 5

설명

  • Default export와 Named export를 한 줄에 동시에 가져올 수 있음
  • Default는 앞에, Named는 `{}` 안에 작성
  • 별칭도 함께 사용 가능

핵심 정리

CommonJS vs ES Module 비교

비교 항목 CommonJS ES Module
내보내기 `module.exports = { }` `export` / `export default`
가져오기 `require()` `import` / `import from`
확장자 `.js` (생략 가능) `.js` (생략 불가)
실행 시점 런타임에 동기 로딩 파일 파싱 시 정적 로딩
사용 환경 Node.js 전용 Node.js + 브라우저

Export 종류

종류 문법 특징
Named Export `export function func() {}` 이름 그대로 import 해야 함, 여러 개 가능
Default Export `export default function() {}` 파일당 1개만, import 시 이름 자유롭게

Import 방법 총정리

// 1. Default import
import multiply from "./math.js";

// 2. Named import
import { add, sub } from "./math.js";

// 3. 별칭 사용
import { add as plus } from "./math.js";

// 4. 전체 import
import * as math from "./math.js";

// 5. Default + Named 동시
import multiply, { add, sub } from "./math.js";

// 6. Default + Named + 별칭 조합
import multiply, { add as plus, sub as minus } from "./math.js";

사용 팁

ES Module 사용하기 (package.json 설정)

ES Module을 사용하려면 package.json에 다음을 추가해야 함

{
  "type": "module"
}

또는 파일 확장자를 `.mjs`로 변경하면 됨


주의사항

1. ES Module에서는 확장자 필수!

   // 안됨
   import { add } from "./math";
   
   // 됨
   import { add } from "./math.js";

 

2. CommonJS와 ES Module은 섞어 쓸 수 없음

  • 한 프로젝트에서는 하나의 방식으로 통일하는 게 좋음

3. Default export는 파일당 1개만!

   // 안됨
   export default function add() {}
   export default function sub() {}  // 에러!

어떤 걸 써야 할까?

CommonJS를 쓰는 경우:

  • 오래된 Node.js 프로젝트
  • npm 패키지들이 대부분 CommonJS일 때
  • 동적 import가 필요할 때 (`require()`는 조건문 안에서도 사용 가능)

ES Module을 쓰는 경우:

  • 새로운 프로젝트 시작할 때 (요즘 트렌드!)
  • 브라우저와 Node.js 모두에서 코드를 돌릴 때
  • 최신 JavaScript 문법을 사용하고 싶을 때
  • React, Vue 같은 프레임워크 사용할 때

 

'React > Node.js' 카테고리의 다른 글

[Node.js] Node.js 소개 및 설정  (0) 2025.11.12
'React/Node.js' 카테고리의 다른 글
  • [Node.js] Node.js 소개 및 설정
이도서
이도서
  • 이도서
    도서의 코딩노트
    이도서
  • 전체
    오늘
    어제
    • 분류 전체보기 (249)
      • Today I Learned (79)
        • 2024 (78)
      • Swift (25)
        • Swift 문법 정리 (19)
        • RxSwift (5)
      • Swift Study (12)
        • Playground (2)
        • Storyboard (9)
        • UIKit (1)
      • Flutter (27)
        • Dart 언어 (16)
        • Flutter Study (11)
      • React (37)
        • HTML & CSS (8)
        • JavaScript 기본 (12)
        • JavaScript 심화 (14)
        • Node.js (2)
        • React (1)
      • Git (3)
      • 코딩테스트 (60)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

    • 개발 공부 공유 링크
  • 인기 글

  • 태그

    DART
    Flutter
    javascript
    내일배움캠프
    storyboard
    iOS앱개발
    ios
    Til
    function
    html
    코딩테스트 level.1
    javascript 기본
    ios앱개발자
    Swift
    CLASS
    코딩테스트
    객체지향
    React
    함수
    코딩테스트Level.1
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
이도서
[Node.js] 모듈 시스템 (CJS vs ES Module)
상단으로

티스토리툴바