17. 코드 정리하고 나누기 (모듈 시스템)/17.4 Node.js의 구조 맛보기

17.4.2 기본 실행 구조 - Node.js 프로젝트 만들기의 첫걸음

thejavascript4kids 2025. 7. 25. 04:23

📘 17.4.2 기본 실행 구조 - Node.js 프로젝트 만들기의 첫걸음

Node.js가 무엇인지 알게 되었으니, 이제 실제로 Node.js 프로젝트를 어떻게 만드는지 배워볼 차례입니다. 마치 새 집을 짓기 위해 설계도를 그리는 것처럼, Node.js 프로젝트도 체계적인 구조가 필요하거든요.

오늘은 그 구조를 차근차근 익혀보면서, 우리만의 작은 프로젝트를 직접 만들어보려 합니다.

🧠 먼저 용어를 알아볼까요?

새로운 프로젝트 세계로 들어가기 전에, 알아두어야 할 말들이 있습니다.

용어 의미
시작점 프로그램이 시작되는 가장 중요한 첫 번째 파일을 말합니다.
패키지 관련된 코드와 파일들을 하나로 묶어서 배포하는 단위입니다.
프로젝트 설명서 Node.js 프로젝트의 모든 정보와 설정을 담은 특별한 파일입니다.
파일 범위 각 파일 안에서만 사용할 수 있는 변수와 함수들의 범위를 의미합니다.

✨ Node.js 프로젝트의 핵심 개념

Node.js 프로젝트는 마치 잘 정리된 책장과 같아요. 모든 것이 제자리에 있고, 어디에 무엇이 있는지 쉽게 찾을 수 있도록 체계적으로 구성되어 있답니다.

일반적으로 Node.js 프로젝트는 하나의 시작 파일에서 출발해요. 이 파일을 시작점이라고 부르는데, 보통 index.jsapp.js라는 이름을 가져요. 마치 책의 첫 페이지처럼, 프로그램이 시작되는 곳이죠.

그리고 프로젝트에는 package.json이라는 매우 중요한 파일이 있어요. 이 파일은 프로젝트의 신분증과 같은 역할을 해요. 프로젝트의 이름, 버전, 필요한 다른 프로그램들의 목록 등 모든 중요한 정보가 들어있답니다.

각각의 파일은 자신만의 공간을 가져요. 이를 파일 범위라고 하는데, 마치 각자의 방에서 놀고 있는 형제자매들처럼, 서로의 물건을 함부로 건드릴 수 없어요. 하지만 필요할 때는 requireimport를 통해 정중하게 빌려줄 수 있답니다.

비유로 이해하기: 잘 정리된 우리 집

Node.js 프로젝트를 '잘 정리된 우리 집'에 비유해서 이해해 보겠습니다.

현관문(index.js)이 집의 시작점이에요. 손님들이 오면 가장 먼저 현관문을 통해 들어오죠. 여기서 집안의 다른 방들로 안내해 줍니다.

집 설계도(package.json)에는 이 집에 대한 모든 정보가 적혀있어요. 몇 층 집인지, 어떤 가구가 필요한지, 언제 지어졌는지 등의 정보가 모두 들어있죠.

각각의 방(모듈)들은 서로 다른 용도를 가져요. 주방에서는 요리를 하고, 거실에서는 가족이 모이고, 공부방에서는 숙제를 해요. 각 방의 물건들은 그 방에서만 사용하지만, 필요하면 다른 방으로 가져갈 수도 있어요.

복도와 문(require/import)을 통해 방과 방 사이를 이동할 수 있어요. 주방에서 만든 맛있는 음식을 거실로 가져가는 것처럼, 한 모듈에서 만든 유용한 함수를 다른 모듈에서 사용할 수 있답니다.

🎯 체계적인 프로젝트 구조를 만드는 이유

왜 이렇게 복잡하게 프로젝트를 구조화해야 할까요? 정말 중요한 이유들이 있어요.

첫째로 코드를 찾기 쉬워져요. 마치 정리된 책상에서 필요한 물건을 빨리 찾는 것처럼, 잘 정리된 프로젝트에서는 원하는 코드를 쉽게 찾을 수 있어요.

둘째로 여러 사람이 함께 작업하기 좋아요. 각자 맡은 부분이 명확하게 나뉘어 있어서, 친구들과 함께 큰 프로젝트를 만들 때도 서로 방해하지 않고 작업할 수 있어요.

셋째로 문제가 생겼을 때 고치기 쉬워요. 어디에 문제가 있는지 쉽게 찾을 수 있고, 한 부분을 고쳐도 다른 부분에 영향을 주지 않아요.

마지막으로 새로운 기능을 추가하기 편해요. 새로운 방을 집에 추가하는 것처럼, 새로운 모듈을 프로젝트에 쉽게 추가할 수 있어요.

⚙️ Node.js 프로젝트의 기본 구조

일반적인 Node.js 프로젝트는 다음과 같은 구조를 가져요.

우리의_프로젝트/
  ├── node_modules/       # npm으로 설치한 도구들이 저장되는 창고
  ├── package.json        # 프로젝트의 신분증
  ├── package-lock.json   # 도구들의 정확한 버전 정보
  ├── index.js            # 프로그램이 시작되는 현관문
  ├── config/             # 설정 파일들을 모아둔 방
  │   └── config.js
  ├── utils/              # 유용한 도구들을 모아둔 창고
  │   └── helpers.js
  └── src/                # 주요 코드들을 모아둔 방
      ├── models/         # 데이터 설계도들
      ├── controllers/    # 일 처리 담당자들
      └── routes/         # 길 안내 담당자들

🧪 첫 번째 Node.js 프로젝트 만들어보기

이제 실제로 우리만의 Node.js 프로젝트를 단계별로 만들어보겠습니다.

🔹 예제 1: 프로젝트 폴더 만들고 설정하기

먼저 우리의 첫 번째 프로젝트를 위한 집을 짓겠습니다.

# 1단계: 프로젝트 폴더 만들기 (새 집 짓기)
mkdir my-first-node-project
cd my-first-node-project

# 2단계: package.json 파일 만들기 (집 설계도 그리기)
npm init -y

이 명령어를 실행하면 package.json이라는 파일이 생겨요. 이 파일을 열어보면 우리 프로젝트에 대한 기본 정보가 들어있답니다.

🔹 예제 2: 메인 시작 파일 만들기

이제 프로그램이 시작되는 현관문을 만들어보겠습니다.

// index.js 파일 - 우리 집의 현관문
// 다른 방(모듈)에서 필요한 것들을 가져와요
const config = require('./config');
const utils = require('./utils');

// 프로그램이 시작될 때 인사말을 해요
console.log('🎉 안녕하세요! 우리의 첫 번째 Node.js 프로그램이 시작됐어요!');

// 설정 정보를 확인해요
console.log(`📋 현재 환경: ${config.environment}`);
console.log(`🏠 프로젝트 이름: ${config.projectName}`);

// 유용한 도구 함수를 사용해서 인사말을 만들어요
const greeting = utils.createGreeting('꼬마 개발자');
console.log(greeting);

// 현재 시간을 예쁘게 보여줘요
const formattedTime = utils.getCurrentTime();
console.log(`⏰ 현재 시간: ${formattedTime}`);

// 프로그램이 성공적으로 시작되었다고 알려주는 함수
function startApplication() {
  console.log('✅ 프로그램이 성공적으로 시작되었습니다!');
  console.log('🚀 이제 멋진 코딩 여행을 시작해볼까요?');
}

// 프로그램 시작!
startApplication();

🔹 예제 3: 설정 파일과 유틸리티 파일 만들기

이제 다른 방들도 만들어보겠습니다.

config.js - 설정을 관리하는 방:

// config.js 파일 - 프로젝트 설정을 관리하는 방
// 프로젝트에 필요한 설정들을 모아두었어요

const config = {
  // 프로젝트의 기본 정보
  projectName: "나의 첫 번째 Node.js 프로젝트",
  version: "1.0.0",
  environment: "개발중", // 개발중, 테스트중, 완성 등

  // 포트 번호 (서버를 만들 때 사용해요)
  port: 3000,

  // 디버그 모드 (문제 해결을 위한 상세 정보 표시)
  debug: true,

  // 개발자 정보
  developer: "꼬마 개발자"
};

// 다른 파일에서 이 설정들을 사용할 수 있도록 내보내요
module.exports = config;

utils.js - 유용한 도구들을 모아둔 창고:

// utils.js 파일 - 유용한 도구 함수들을 모아둔 창고
// 여러 곳에서 자주 사용하는 함수들을 만들어두었어요

// 예쁜 인사말을 만들어주는 함수
function createGreeting(name) {
  const greetings = [
    "안녕하세요",
    "반갑습니다", 
    "환영합니다",
    "좋은 하루예요"
  ];

  // 인사말 중에서 랜덤하게 하나를 선택해요
  const randomIndex = Math.floor(Math.random() * greetings.length);
  const selectedGreeting = greetings[randomIndex];

  return `${selectedGreeting}, ${name}님! 🌟`;
}

// 현재 시간을 예쁘게 포맷팅해주는 함수
function getCurrentTime() {
  const now = new Date();
  const options = {
    year: 'numeric',
    month: 'long', 
    day: 'numeric',
    hour: 'numeric',
    minute: 'numeric',
    second: 'numeric'
  };

  return now.toLocaleDateString('ko-KR', options);
}

// 숫자를 예쁘게 포맷팅해주는 함수
function formatNumber(number) {
  return number.toLocaleString('ko-KR');
}

// 다른 파일에서 이 함수들을 사용할 수 있도록 내보내요
module.exports = {
  createGreeting,
  getCurrentTime,
  formatNumber
};

🔄 프로젝트 실행하기

이제 우리가 만든 프로젝트를 실행해보겠습니다. 터미널에서 다음 명령어를 입력해요:

node index.js

그러면 다음과 같은 결과를 볼 수 있을 거예요:

🎉 안녕하세요! 우리의 첫 번째 Node.js 프로그램이 시작됐어요!
📋 현재 환경: 개발중
🏠 프로젝트 이름: 나의 첫 번째 Node.js 프로젝트
좋은 하루예요, 꼬마 개발자님! 🌟
⏰ 현재 시간: 2025년 6월 15일 오후 2시 30분 15초
✅ 프로그램이 성공적으로 시작되었습니다!
🚀 이제 멋진 코딩 여행을 시작해볼까요?

🧚‍♀️ 이야기로 다시 배우기: 작은 마을 만들기

지금까지 배운 내용을 하나의 이야기로 다시 정리해볼게요.

한때 작은 마을을 만들고 싶어하는 친구가 있었어요. 이 친구는 Node.js라는 특별한 도구를 사용해서 자신만의 특별한 마을을 만들기로 했죠.

먼저 마을 전체의 설계도(package.json)를 그렸어요. 마을의 이름, 언제 만들어졌는지, 어떤 건물들이 필요한지 모든 계획을 세심하게 적어두었답니다.

그다음에는 마을의 중심가(index.js)를 만들었어요. 이곳은 모든 방문객들이 가장 먼저 도착하는 곳으로, 마을의 다른 모든 곳으로 안내해주는 역할을 했어요.

설정 관리소(config.js)에는 마을의 모든 규칙과 설정이 보관되어 있어요. 마을의 이름, 개장 시간, 특별한 규칙들이 모두 여기에 정리되어 있죠.

도구 창고(utils.js)에는 마을 사람들이 자주 사용하는 유용한 도구들이 보관되어 있어요. 예쁜 인사말을 만들어주는 도구, 시간을 알려주는 시계, 숫자를 예쁘게 꾸며주는 도구 등이 있답니다.

이렇게 체계적으로 마을을 만들어두니까, 나중에 새로운 건물을 추가하거나 문제가 생겼을 때 고치기도 쉬웠어요. 그리고 다른 친구들이 와서 도움을 줄 때도 어디에 무엇이 있는지 쉽게 알 수 있었답니다.

🧠 자주 하는 실수와 주의할 점

Node.js 프로젝트를 만들 때 자주 하는 실수들을 미리 알아두면 도움이 될 거예요.

❌ 실수 1: 모든 코드를 한 파일에 몰아넣기

// 이렇게 하면 안 돼요! (너무 긴 index.js)
const config = { /* 모든 설정 */ };
function utility1() { /* 함수 1 */ }
function utility2() { /* 함수 2 */ }
function utility3() { /* 함수 3 */ }
// ... 수백 줄의 코드

이렇게 하면 나중에 코드를 찾기도 어렵고, 수정하기도 힘들어져요. 기능별로 파일을 나누는 것이 좋아요.

❌ 실수 2: package.json을 제대로 관리하지 않기

// package.json에 중요한 정보가 빠져있거나 잘못되어 있으면
// 다른 사람이 프로젝트를 이해하기 어려워요

package.json은 프로젝트의 신분증이니까 정확하고 상세하게 작성해야 해요.

❌ 실수 3: 모듈을 내보내는 것을 까먹기

// utils.js에서 함수를 만들었는데...
function createGreeting(name) {
  return `안녕하세요, ${name}님!`;
}

// module.exports를 안 하면 다른 파일에서 사용할 수 없어요!
// module.exports = { createGreeting }; // 이걸 꼭 써줘야 해요!

✏️ 연습문제로 개념 다지기

새로 얻은 지식에 조금씩 익숙해져 볼까요. 연습을 통해 Node.js 프로젝트 구조가 무엇인지 더 깊이 느껴보시길 바랍니다.

Ex1) 학생 정보를 관리하는 시스템을 만들어보자

// student.js - 학생 정보를 관리하는 모듈
// 학생 정보를 담는 특별한 틀을 만들어주는 함수
function createStudent(name, age, grade, favoriteSubject) {
  return {
    name: name,                    // 학생의 이름을 저장해요
    age: age,                      // 학생의 나이를 저장해요  
    grade: grade,                  // 학생의 학년을 저장해요
    favoriteSubject: favoriteSubject, // 좋아하는 과목을 저장해요
    // 학생이 자기소개를 하는 특별한 기능
    introduce: function() {
      return `안녕하세요! 저는 ${this.grade}학년 ${this.name}입니다. 
              나이는 ${this.age}살이고, ${this.favoriteSubject}를 좋아해요!`;
    }
  };
}

// 여러 학생들을 저장할 수 있는 목록
let students = [];

// 새로운 학생을 목록에 추가하는 함수
function addStudent(name, age, grade, favoriteSubject) {
  const newStudent = createStudent(name, age, grade, favoriteSubject); // 새 학생 정보 만들기
  students.push(newStudent);                                           // 목록에 추가하기
  console.log(`${name} 학생이 추가되었습니다!`);                        // 성공 메시지 보여주기
}

// 모든 학생 목록을 예쁘게 보여주는 함수
function listAllStudents() {
  console.log("=== 전체 학생 목록 ===");
  // for문을 사용해서 학생 목록을 하나씩 확인해요
  for (let i = 0; i < students.length; i++) {
    const student = students[i];                                     // i번째 학생 정보 가져오기
    console.log(`${i + 1}. ${student.name} (${student.grade}학년)`); // 순번과 이름, 학년을 출력해요
  }
}

// 다른 파일에서 이 함수들을 사용할 수 있도록 내보내기
module.exports = {
  addStudent,
  listAllStudents,
  students
};

Ex2) 위의 학생 관리 시스템을 사용하는 메인 파일을 만들어보자

// index.js - 학생 관리 프로그램의 시작점
// 학생 관리 모듈을 우리 프로그램으로 가져와요
const studentManager = require('./student');

// 프로그램이 시작될 때 인사말을 해요
console.log("🎓 학생 관리 프로그램을 시작합니다!");
console.log("==============================");

// 몇 명의 학생들을 시스템에 추가해보기
studentManager.addStudent("민수", 11, 5, "수학");    // 첫 번째 학생 추가
studentManager.addStudent("영희", 10, 4, "과학");    // 두 번째 학생 추가
studentManager.addStudent("철수", 12, 6, "체육");    // 세 번째 학생 추가
studentManager.addStudent("지수", 11, 5, "미술");    // 네 번째 학생 추가

console.log(""); // 줄 간격을 위한 빈 줄

// 등록된 모든 학생들의 목록을 보여주기
studentManager.listAllStudents();

console.log(""); // 줄 간격을 위한 빈 줄

// 각 학생이 직접 자기소개를 하는 시간
console.log("=== 학생들의 자기소개 ===");
// for문을 사용해서 학생들의 자기소개를 하나씩 출력해요
for (let i = 0; i < studentManager.students.length; i++) {
  const student = studentManager.students[i];        // i번째 학생 정보 가져오기
  console.log(student.introduce());                  // 각 학생의 자기소개를 출력해요
}

console.log(""); // 줄 간격을 위한 빈 줄
console.log("✨ 프로그램이 완료되었습니다!");

Ex3) 도서관의 책들을 관리하는 시스템을 만들어보자

// library.js - 도서관 관리 모듈
// 책 정보를 담는 특별한 틀을 만들어주는 함수
function createBook(title, author, pages, isAvailable = true) {
  return {
    title: title,                // 책 제목을 저장해요
    author: author,              // 책 저자를 저장해요
    pages: pages,                // 책 페이지 수를 저장해요
    isAvailable: isAvailable,    // 대출 가능 여부를 저장해요 (기본값: 가능)
    // 책 정보를 예쁘게 보여주는 특별한 기능
    getInfo: function() {
      const status = this.isAvailable ? "대출 가능" : "대출 중";    // 상태 확인
      return `📖 ${this.title} - ${this.author} 저 (${this.pages}쪽) [${status}]`;
    }
  };
}

// 도서관의 모든 책들을 저장할 수 있는 목록
let books = [];

// 새로운 책을 도서관에 추가하는 함수
function addBook(title, author, pages) {
  const newBook = createBook(title, author, pages);  // 새 책 정보 만들기
  books.push(newBook);                               // 책 목록에 추가하기
  console.log(`"${title}" 책이 도서관에 추가되었습니다!`); // 성공 메시지 보여주기
}

// 도서관의 모든 책 목록을 보여주는 함수
function showAllBooks() {
  console.log("=== 도서관 전체 도서 목록 ===");
  if (books.length === 0) {                      // 만약 책이 하나도 없다면
    console.log("도서관에 책이 없습니다.");        // 안내 메시지 출력
    return;                                      // 함수 종료
  }

  // for문을 사용해서 책 목록을 하나씩 확인해요
  for (let i = 0; i < books.length; i++) {
    const book = books[i];                           // i번째 책 정보 가져오기
    console.log(`${i + 1}. ${book.getInfo()}`);     // 순번과 책 정보를 출력해요
  }
}

// 지금 빌릴 수 있는 책만 골라서 보여주는 함수
function showAvailableBooks() {
  console.log("=== 대출 가능한 도서 ===");

  // 먼저 대출 가능한 책이 있는지 확인해요
  let availableCount = 0;
  for (let i = 0; i < books.length; i++) {
    if (books[i].isAvailable) {                    // 만약 이 책이 대출 가능하다면
      availableCount++;                            // 개수를 하나 늘려요
    }
  }

  if (availableCount === 0) {                      // 만약 빌릴 수 있는 책이 없다면
    console.log("현재 대출 가능한 책이 없습니다."); // 안내 메시지 출력
    return;                                        // 함수 종료
  }

  // 대출 가능한 책들을 하나씩 출력해요
  let displayIndex = 1;                            // 출력용 순번
  for (let i = 0; i < books.length; i++) {
    const book = books[i];                         // i번째 책 정보 가져오기
    if (book.isAvailable) {                        // 만약 이 책이 대출 가능하다면
      console.log(`${displayIndex}. ${book.getInfo()}`); // 순번과 책 정보를 출력해요
      displayIndex++;                              // 다음 출력용 순번으로 증가
    }
  }
}

// 다른 파일에서 이 함수들과 목록을 사용할 수 있도록 내보내기
module.exports = {
  addBook,
  showAllBooks,
  showAvailableBooks,
  books
};

지금까지 Node.js 프로젝트의 기본 실행 구조에 대해 자세히 알아보았습니다. 체계적인 프로젝트 구조는 마치 잘 정리된 집과 같아서, 나중에 코드를 찾거나 수정하기가 훨씬 쉬워져요. 앞으로 더 복잡한 프로젝트를 만들 때도 이 기본 구조를 기억하면서 체계적으로 개발해 나가면 됩니다!

📝 복습 문제 - 이전 단원 내용 기억하기

이번 시간에 새로운 내용을 배웠으니, 이전에 배운 중요한 내용도 복습해볼까요?

🔢 Node.js 기본 개념 복습 (17.4.1단원에서 배운 내용)

문제 1: Node.js가 특별한 이유 3가지를 설명해보세요.

해답:

  1. 브라우저 밖에서도 자바스크립트 실행 가능: 원래 자바스크립트는 웹 브라우저에서만 작동했지만, Node.js 덕분에 컴퓨터의 어느 곳에서든 실행할 수 있게 되었어요.

  2. 서버 프로그램 개발 가능: 웹사이트의 뒷부분(백엔드)을 자바스크립트로 만들 수 있어서, 하나의 언어로 전체 웹 애플리케이션을 개발할 수 있어요.

  3. 이벤트 기반으로 효율적: 여러 가지 일을 동시에 처리할 수 있어서, 많은 사용자가 동시에 접속하는 서비스를 효율적으로 만들 수 있어요.

문제 2: 브라우저 자바스크립트와 Node.js 자바스크립트의 차이점을 2가지 이상 설명해보세요.

해답:

  1. 실행 환경: 브라우저 자바스크립트는 웹페이지 내에서만 실행되지만, Node.js는 컴퓨터 시스템 어디서나 실행될 수 있어요.

  2. 파일 시스템 접근: Node.js는 컴퓨터의 파일을 읽고 쓰는 기능을 제공하지만, 브라우저 자바스크립트는 보안상의 이유로 이런 기능이 제한되어 있어요.

  3. DOM 조작: 브라우저 자바스크립트는 HTML 요소를 조작할 수 있는 DOM API를 제공하지만, Node.js에는 이런 기능이 없어요.

해설: Node.js는 자바스크립트를 브라우저 밖에서도 실행할 수 있게 해주는 특별한 환경이에요. 그래서 브라우저와는 다른 특별한 능력들을 가지고 있답니다.

✅ 학습 완료 체크리스트

이번 시간에 배운 내용들을 모두 이해했는지 확인해보세요!

학습 내용 이해했나요?
Node.js 프로젝트 기본 구조
package.json의 역할
모듈 시스템 활용
자주 하는 실수들
실전 예제 이해

📂 마무리 정보

오늘 배운 17.4.2 내용이 여러분의 자바스크립트 지식 상자에 잘 저장되었나요? Node.js 프로젝트의 기본 구조는 앞으로 모든 Node.js 개발의 기초가 될 거예요. 다음 시간에는 터미널에서 자바스크립트를 실행하는 방법에 대해 더 자세히 알아볼 거예요!

기억할 점: 체계적인 프로젝트 구조는 코드를 찾기 쉽게 하고, 유지보수를 편하게 만들어준다는 점을 꼭 기억해두세요.


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