당신의 승리를 축하하기: 한 주를 잊을 수 없게 만든 이유

발행: (2026년 4월 29일 AM 10:08 GMT+9)
6 분 소요
원문: Dev.to

Source: Dev.to

개발자들은 종종 깨진 부분, 다음에 할 일, 아직 배포하지 않은 것에 집중합니다. 하지만 성장은 실제로 잘 된 일을 멈춰서 되돌아볼 때 일어납니다 — 고친 작은 버그, 배포한 기능, 혹은 마침내 이해한 새로운 개념 말이죠.

이번 튜토리얼에서는 Node.js와 Express를 사용해 **“주간 성과 트래커”**를 간단히 만들어 보겠습니다. 데이터는 JSON 파일에 저장됩니다. 초보자도 쉽게 따라 할 수 있는 코드 중심 예제로, 한 주씩 여러분의 진행 상황을 축하할 수 있게 설계되었습니다.

튜토리얼을 마치면 다음과 같은 기능을 갖춘 웹 앱을 얻게 됩니다:

  • 주간 성과를 추가하기
  • 모든 성과 보기
  • 이모지 콘페티 🎉 로 진행 상황을 축하하기

시작해 볼까요?

1단계: 프로젝트 설정

새 디렉터리를 만들고 Node.js 프로젝트를 초기화합니다:

mkdir weekly-wins-tracker
cd weekly-wins-tracker
npm init -y

Express 설치:

npm install express

nodemon을 설치하여 개발 중 자동 재시작을 가능하게 합니다 (선택 사항이지만 권장됩니다):

npm install --save-dev nodemon

package.json 스크립트를 업데이트합니다:

{
  "scripts": {
    "start": "node server.js",
    "dev": "nodemon server.js"
  }
}

Step 2: 서버 만들기

server.js 생성:

const express = require('express');
const fs = require('fs');
const path = require('path');
const app = express();
const PORT = 3000;

// Middleware to parse JSON and serve static files
app.use(express.json());
app.use(express.static('public'));

우리는 다음을 사용합니다:

  • express.json()은 들어오는 JSON을 파싱합니다
  • express.static('public')은 HTML, CSS, 그리고 JS 파일을 제공합니다

Step 3: 데이터 저장소 설정

우리는 승리를 wins.json이라는 JSON 파일에 저장합니다.

프로젝트 루트에 wins.json을 생성하세요:

[]

승리를 읽고 쓰는 헬퍼 함수를 추가합니다:

const WINS_FILE = path.join(__dirname, 'wins.json');

// Read wins from file
function readWins() {
  const data = fs.readFileSync(WINS_FILE);
  return JSON.parse(data);
}

// Write wins to file
function writeWins(wins) {
  fs.writeFileSync(WINS_FILE, JSON.stringify(wins, null, 2));
}

4단계: API 엔드포인트 구축

우리는 세 개의 라우트를 만들 것입니다:

  • GET /wins – 모든 승리 항목 가져오기
  • POST /wins – 새로운 승리 항목 추가하기
  • GET / – 프론트엔드 제공하기

라우트를 추가합니다:

// Get all wins
app.get('/wins', (req, res) => {
  try {
    const wins = readWins();
    res.json(wins);
  } catch (err) {
    res.status(500).json({ error: 'Failed to read wins' });
  }
});

// Add a new win
app.post('/wins', (req, res) => {
  const { text } = req.body;

  if (!text || text.trim() === '') {
    return res.status(400).json({ error: 'Win text is required' });
  }

  const newWin = {
    id: Date.now().toString(),
    text: text.trim(),
    date: new Date().toISOString().split('T')[0]
  };

  const wins = readWins();
  wins.push(newWin);
  writeWins(wins);

  res.status(201).json(newWin);
});

server.js 파일의 마지막에 서버를 시작하는 것을 잊지 마세요:

app.listen(PORT, () => {
  console.log(`Server is running on http://localhost:${PORT}`);
});

5단계: 프론트엔드 만들기

public 폴더를 만들고 index.html을 추가하세요:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Weekly Wins Tracker</title>
  <style>
    body {
      font-family: 'Segoe UI', sans-serif;
      max-width: 600px;
      margin: 40px auto;
      padding: 20px;
      background: #f9f9ff;
      color: #333;
    }
    h1 { color: #4a4a98; text-align: center; }
    input, button {
      padding: 10px;
      margin: 10px 0;
      width: 100%;
      box-sizing: border-box;
    }
    button {
      background: #4a4a98;
      color: white;
      border: none;
      cursor: pointer;
    }
    ul {
      list-style: none;
      padding: 0;
    }
    li {
      background: white;
      margin: 8px 0;
      padding: 12px;
      border-radius: 6px;
      box-shadow: 0 1px 3px rgba(0,0,0,0.1);
    }
    .confetti {
      font-size: 1.5em;
      margin-right: 8px;
    }
  </style>
</head>
<body>
  <h1>🎉 Celebrate Your Wins</h1>

  <input type="text" id="winInput" placeholder="What did you achieve this week?" />
  <button onclick="addWin()">Add Win</button>

  <ul id="winsList"></ul>

  <script>
    // Load wins on page load
    window.onload = loadWins;

    async function loadWins() {
      const res = await fetch('/wins');
      const wins = await res.json();
      const list = document.getElementById('winsList');
      list.innerHTML = '';
      wins.forEach(win => {
        const li = document.createElement('li');
        li.innerHTML = `🎊${win.text} (${win.date})`;
        list.appendChild(li);
      });
    }

    async function addWin() {
      const input = document.getElementById('winInput');
      const text = input.value.trim();
      if (!text) return;

      const res = await fetch('/wins', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ text })
      });

      if (res.ok) {
        input.value = '';
        loadWins();
      } else {
        const err = await res.json();
        alert(err.error);
      }
    }
  </script>
</body>
</html>

이제 앱을 실행하세요:

npm run dev   # or npm start

브라우저에서 http://localhost:3000을 열고, 몇 개의 승리를 추가하면, 축하 효과와 함께 리스트가 늘어나는 것을 볼 수 있습니다! 🎉

0 조회
Back to Blog

관련 글

더 보기 »