17. 코드 정리하고 나누기 (모듈 시스템)/17.3 CommonJS (Node.js 방식)

17.3.1 module.exports 사용하기 - Node.js의 특별한 선물상자

thejavascript4kids 2025. 7. 25. 04:18

📘 17.3.1 module.exports 사용하기 - Node.js의 특별한 선물상자

어렸을 때, 생일선물을 받으면 어떤 마음이었나요? 포장지를 조심스럽게 뜯어내며 "안에 뭐가 들어있을까?" 하고 설레던 그 순간들 말이에요. 작은 상자 안에 누군가의 마음이 고스란히 담겨 있었죠.

프로그래밍에도 그런 선물상자가 있어요. 우리가 정성껏 만든 함수나 변수들을 예쁜 상자에 담아서 다른 사람들에게 전해줄 수 있는 특별한 방법이 있거든요. 오늘은 Node.js라는 환경에서 사용하는 module.exports라는 선물상자에 대해 이야기해보려고 해요.

🧠 새로운 단어들과 친해지기

단어 쉬운 설명
CommonJS Node.js에서 사용하는 모듈 시스템의 이름
module.exports 우리가 만든 코드를 다른 파일에 보내주는 특별한 상자
exports module.exports를 더 짧게 쓸 수 있는 별명
require 다른 파일에서 만든 코드를 가져오는 명령어

✨ module.exports가 뭐예요?

module.exports는 Node.js에서 정말 중요한 개념이에요. 이것은 마치 할머니가 김치를 담아주시던 낡은 밀폐용기와 같은 역할을 해요. 할머니는 김치뿐만 아니라 다른 반찬들도 그 용기에 담아주셨거든요. 그럼 우리는 집에 가서 그 용기를 열어보며 할머니의 정성이 담긴 음식들을 하나씩 꺼내 먹을 수 있었죠.

우리가 웹 브라우저에서 사용하던 exportimport가 있다면, Node.js 서버 환경에서는 module.exportsrequire를 사용해요. 둘 다 같은 일을 하지만, 사용하는 방법이 조금 달라요.

export가 각각의 음식에 이름표를 붙여서 개별적으로 나눠주는 것이라면, module.exports하나의 큰 도시락에 여러 음식을 모두 담아서 한 번에 건네주는 것과 같아요.

🎯 왜 module.exports를 사용할까요?

1. 서버 프로그래밍에 최적화되어 있어요

Node.js로 웹서버를 만들 때 여러 기능들을 모듈로 나누어 관리하면 코드가 훨씬 깔끔해져요.

2. 한 번에 여러 기능을 묶어서 보낼 수 있어요

하나의 상자에 관련된 모든 기능을 담아서 보내니까, 받는 쪽에서도 한 번에 필요한 모든 것을 얻을 수 있어요.

3. 오랫동안 사용되어 온 안정적인 방법이에요

Node.js가 처음 만들어질 때부터 사용되어 온 방식이라서 안정적이에요.

⚙️ module.exports 사용 방법

module.exports를 사용하는 방법은 여러 가지가 있어요.

방법 1: 함수 하나만 내보내기

// greet.js
module.exports = function(name) {
  return `안녕하세요, ${name}님!`;
};

// app.js
const greet = require('./greet.js');
console.log(greet("민수")); // "안녕하세요, 민수님!"

방법 2: 여러 기능을 객체로 묶어서 내보내기

// math.js
module.exports = {
  add: function(a, b) { return a + b; },
  subtract: function(a, b) { return a - b; }
};

// app.js
const math = require('./math.js');
console.log(math.add(5, 3));      // 8
console.log(math.subtract(5, 3)); // 2

방법 3: exports 별명 사용하기

// calculator.js
exports.multiply = function(a, b) { return a * b; };
exports.divide = function(a, b) { return a / b; };

// app.js
const calc = require('./calculator.js');
console.log(calc.multiply(4, 3)); // 12
console.log(calc.divide(12, 3));  // 4

주의! exports에 직접 객체를 할당하면 안 돼요. exports = { ... }는 작동하지 않아요!

🧪 실제 예제로 연습하기

🔹 예제 1: 학교 급식 메뉴 관리

// menu.js
const weeklyMenu = {
  "월요일": "김치찌개, 밥, 계란말이",
  "화요일": "카레라이스, 치킨너겟",
  "수요일": "비빔밥, 미역국",
  "목요일": "스파게티, 마늘빵",
  "금요일": "불고기덮밥, 김치"
};

function getMenuByDay(day) {
  if (weeklyMenu[day]) {
    return `${day}: ${weeklyMenu[day]}`;
  } else {
    return `${day}은(는) 급식이 없는 날입니다.`;
  }
}

function getWeeklyMenu() {
  let menuList = "📅 이번 주 급식 메뉴:\n";
  for (let day in weeklyMenu) {
    menuList += `${day}: ${weeklyMenu[day]}\n`;
  }
  return menuList;
}

// 모든 기능을 하나의 객체에 담아서 내보내기
module.exports = {
  weeklyMenu: weeklyMenu,
  getMenuByDay: getMenuByDay,
  getWeeklyMenu: getWeeklyMenu
};

// school-app.js
const menu = require('./menu.js');

console.log("🍽️ 학교 급식 정보 시스템");
console.log(menu.getMenuByDay("수요일"));  // "수요일: 비빔밥, 미역국"
console.log(menu.getWeeklyMenu());        // 전체 주간 메뉴

🔹 예제 2: 동물원 관리 시스템

// animals.js
const zooAnimals = [
  { name: "바둑이", type: "사자", age: 5, sound: "어흥!" },
  { name: "하늘이", type: "코끼리", age: 12, sound: "뿌우~" },
  { name: "별이", type: "원숭이", age: 3, sound: "끽끽!" }
];

// exports를 사용해서 기능들을 하나씩 추가하기
exports.listAllAnimals = function() {
  let animalList = "🦁 동물원 동물 목록:\n";
  for (let i = 0; i < zooAnimals.length; i++) {
    const animal = zooAnimals[i];
    animalList += `${i + 1}. ${animal.name} (${animal.type}, ${animal.age}살)\n`;
  }
  return animalList;
};

exports.makeAnimalSound = function(animalName) {
  for (let i = 0; i < zooAnimals.length; i++) {
    const animal = zooAnimals[i];
    if (animal.name === animalName) {
      return `${animal.name}: ${animal.sound}`;
    }
  }
  return `${animalName}라는 동물을 찾을 수 없어요.`;
};

exports.addNewAnimal = function(name, type, age, sound) {
  const newAnimal = { name, type, age, sound };
  zooAnimals.push(newAnimal);
  return `${name} (${type})이(가) 동물원에 새로 왔어요!`;
};

// zoo-app.js
const animals = require('./animals.js');

console.log("🦁 동물원 관리 시스템");
console.log(animals.listAllAnimals());
console.log(animals.makeAnimalSound("바둑이")); // "바둑이: 어흥!"
console.log(animals.addNewAnimal("복실이", "토끼", 2, "깡총!"));

🚨 자주 하는 실수들

❌ 실수 1: exports에 직접 객체 할당하기

// 잘못된 방법
exports = {
  add: function(a, b) { return a + b; }
};  // ❌ 작동하지 않아요!

// 올바른 방법
module.exports = {
  add: function(a, b) { return a + b; }
};  // ✅ 이렇게 해야 해요!

❌ 실수 2: require 경로 실수

// 잘못된 방법
const math = require('math.js');     // ❌ ./ 빼먹음!

// 올바른 방법
const math = require('./math.js');   // ✅ 경로 표시 필요!

✏️ 연습 문제를 시작하기 전에

이제 여러분이 직접 module.exports를 사용해볼 시간이에요. 처음에는 웹브라우저에서 사용하던 방법과 달라서 조금 어색할 수도 있어요. 마치 새로운 도시에 이사를 가서 길을 익히는 것처럼 말이에요.

하지만 걱정하지 마세요. 천천히 하나씩 따라하다 보면 자연스럽게 익숙해질 거예요. 무엇보다 이 방법을 익혀두면 나중에 서버 프로그래밍을 할 때 정말 유용하게 쓸 수 있어요.

문제 1: 게임 캐릭터 관리 모듈 만들기

// character.js
const character = {
  name: "용사",
  level: 1,
  hp: 100,
  exp: 0
};

function levelUp() {
  character.level++;
  character.hp += 20;
  return `레벨업! 현재 레벨: ${character.level}`;
}

function gainExp(amount) {
  character.exp += amount;
  if (character.exp >= character.level * 100) {
    character.exp -= character.level * 100;
    return levelUp();
  }
  return `경험치 ${amount} 획득!`;
}

function getStatus() {
  return `${character.name} | 레벨: ${character.level} | HP: ${character.hp}`;
}

module.exports = {
  character: character,
  levelUp: levelUp,
  gainExp: gainExp,
  getStatus: getStatus
};

문제 2: 계산기 모듈 만들기

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

exports.subtract = function(a, b) {
  return a - b;
};

exports.multiply = function(a, b) {
  return a * b;
};

exports.divide = function(a, b) {
  if (b === 0) {
    return "0으로 나눌 수 없습니다!";
  }
  return a / b;
};

// app.js
const calc = require('./calculator.js');

console.log(calc.add(10, 5));      // 15
console.log(calc.subtract(10, 5)); // 5
console.log(calc.multiply(10, 5)); // 50
console.log(calc.divide(10, 5));   // 2

🎯 ES6 모듈과 비교하기

지금까지 배운 ES6 모듈과 CommonJS 모듈을 비교해보겠습니다.

구분 ES6 모듈 CommonJS
환경 브라우저 (웹) Node.js (서버)
내보내기 export module.exports
가져오기 import require
사용법 import { add } from './math.js' const { add } = require('./math.js')

두 방식 모두 같은 목적을 가지고 있어요. 코드를 모듈로 나누어서 재사용하고 관리하기 쉽게 만드는 거죠!

📝 정리하기

오늘은 module.exports에 대해 배웠어요:

  1. module.exports는 Node.js에서 코드를 다른 파일로 내보내는 방법이에요
  2. require로 다른 파일에서 만든 코드를 가져와서 사용해요
  3. exports는 module.exports의 별명이지만, 직접 할당하면 안 돼요
  4. ES6 모듈과 비슷한 목적이지만 사용법이 조금 달라요
  5. 서버 프로그래밍에서 주로 사용해요

module.exports를 잘 사용하면 Node.js에서 더 체계적인 코드를 만들 수 있어요!

✅ 학습 완료 체크리스트

학습 내용 이해했나요?
module.exports의 기본 개념
require로 모듈 가져오기
exports와 module.exports의 차이점
실전 예제 따라하기
ES6 모듈과의 차이점

📂 마무리 정보

오늘 배운 17.3.1 내용이 여러분의 자바스크립트 지식 상자에 잘 저장되었나요? 다음 시간에는 더 재미있는 내용으로 만나요!

기억할 점: module.exports는 할머니의 도시락처럼 소중한 것들을 담아서 나눠주는 따뜻한 방법이에요!



🚀 더 체계적인 JavaScript 학습을 원하신다면?
이 포스팅에서 다룬 내용을 실제로 실습해보세요!
무료 JavaScript 학습 플랫폼에서 단계별 학습과 실시간 코드 실행을 통해
더욱 효과적이고 재미있게 학습하실 수 있습니다.
📝 실시간 코드 실행 📊 학습 진도 관리 👥 체계적 커리큘럼
📚 171개 체계적 학습레슨 · 📋 855개 4지선다 연습문제 · 🆓 완전 무료 · ⚡ 즉시 시작