시작.
1. 폴더 만들고 명령어 npm init -y
기본 설정으로 package.json 만드는 명령어
3. 디렉토리 폴더 views 만들고 views에 index.ejs 생성
간단한 CRUD UI 작성
4. app.js 생성 후
백엔드 서버 구축 후 CRUD API 작성
5. 최종 디렉토리
│
├── app.js # 메인 서버 파일
├── data.json # 데이터 저장 파일
├── package.json
├── package-lock.json
├── node_modules/
└── views/ # EJS 템플릿 파일
└── index.ejs
views/index.ejs
<!DOCTYPE html>
<html lang="en">
<head>
<!-- HTML 문서의 인코딩을 UTF-8로 설정 (한글 등 다양한 문자 지원) -->
<meta charset="UTF-8">
<!-- 페이지 제목 설정 -->
<title>CRUD Example</title>
</head>
<body>
<!-- 페이지의 메인 제목 -->
<h1>ejs CRUD 실습 페이지</h1>
<h2>생성 블록</h2>
<!-- 게시글 생성 폼 -->
<!-- 폼 데이터는 POST 요청으로 /create 경로에 전송 -->
<form action="/create" method="POST">
<!-- 제목 입력 필드 -->
<label for="title">Title:</label>
<input type="text" id="title" name="title" required>
<!-- 설명 입력 필드 -->
<label for="description">Description:</label>
<textarea id="description" name="description" required></textarea>
<!-- 폼 제출 버튼 -->
<button type="submit">Create</button>
</form>
<!-- 구분선 -->
<hr>
<!-- 목록 -->
<h2>Item List</h2>
<!-- 게시글 목록을 출력 -->
<ul>
<!-- `items` 배열의 각 요소를 순회하며 HTML 리스트로 렌더링 -->
<% items.forEach(item => { %>
<li>
<!-- 각 세기글의 제목과 설명 출력 -->
<strong><%= item.title %></strong>: <%= item.description %>
<!-- 수정폼 -->
<!-- 게시글 업데이트 폼 -->
<!-- 특정 아이템의 id를 URL에 포함하여 POST 요청으로 전송 -->
<form action="/edit/<%= item.id %>" method="POST" style="display:inline;">
<!-- 현재 게시글의 제목을 입력 필드로 제공 -->
<input type="text" name="title" value="<%= item.title %>" required>
<!-- 현재 게시굴의 설명을 입력 필드로 제공 -->
<input type="text" name="description" value="<%= item.description %>" required>
<!-- 업데이트 버튼 -->
<button type="submit">Update</button>
</form>
<!-- 삭제폼 -->
<!-- 삭제 폼 -->
<!-- 특정 게시글의 id를 URL에 포함하여 POST 요청으로 전송 -->
<form action="/delete/<%= item.id %>" method="POST" style="display:inline;">
<!-- 삭제 버튼 -->
<button type="submit">Delete</button>
</form>
</li>
<% }); %>
</ul>
</body>
</html>
EJS에서 <%= %>의 역할
- HTML에 데이터를 출력할 때 사용됩니다.
- JavaScript 코드를 실행한 결과를 HTML에 삽입합니다.
- 데이터가 화면에 그대로 렌더링됩니다.
주석 설명 요약
- HTML 구조:
- <!DOCTYPE html>: 문서 타입 선언.
- <html>: HTML 문서의 루트 요소.
- <head>: 메타데이터 및 제목 설정.
- <body>: 실제 콘텐츠가 렌더링되는 부분.
- 게시판 생성 폼:
- /create 경로로 POST 요청을 보냅니다.
- title과 description을 입력받아 서버에 전송.
- 게시판 목록 출력:
- 서버에서 전달된 items 배열을 순회(forEach)하며 리스트를 출력.
- <%= ... %>를 사용해 EJS에서 값을 출력.
- 게시판 수정 폼:
- 각 아이템마다 개별 수정 폼이 생성됩니다.
- id를 URL에 포함하여 어떤 게시글을 수정할지 서버에 전달.
- 기존 제목과 설명을 입력 필드에 기본값으로 설정.
- 게시판 삭제 폼:
- 각 게시글마다 개별 삭제 폼이 생성됩니다.
- id를 URL에 포함하여 삭제 요청을 서버에 전달.
app.js
// Express 모듈을 가져옵니다. Express는 웹 서버를 쉽게 구성할 수 있게 도와주는 프레임워크입니다.
const express = require('express');
// body-parser 모듈을 가져옵니다. 요청에서 전송된 데이터를 읽고 처리하는 데 사용됩니다.
const bodyParser = require('body-parser');
// fs 모듈을 가져옵니다. 파일 시스템과 상호작용(파일 읽기/쓰기)하는 데 사용됩니다.
const fs = require('fs');
// Express 애플리케이션을 초기화합니다.
const app = express();
// 서버가 실행될 포트를 설정합니다.
const PORT = 3000;
// -------------------- 미들웨어 --------------------
// body-parser를 사용해 요청 본문 데이터를 URL-encoded 형식으로 처리할 수 있게 설정합니다.
app.use(bodyParser.urlencoded({ extended: true }));
// EJS를 템플릿 엔진으로 설정합니다. EJS 파일을 렌더링하여 동적으로 HTML을 생성합니다.
app.set('view engine', 'ejs');
// -------------------- 데이터 로드 --------------------
// 서버 실행 시 데이터를 로드합니다.
// 'data.json' 파일의 내용을 읽고 JSON 형식으로 파싱하여 `data` 변수에 저장합니다.
let data = JSON.parse(fs.readFileSync('./data.json', 'utf-8'));
// -------------------- 루트 API --------------------
// 메인 페이지 - 게시글 목록을 읽어서 클라이언트에 전달합니다.
app.get('/', (req, res) => {
// 'index.ejs' 템플릿을 렌더링하며, 현재 `data`를 `items` 변수로 전달합니다.
res.render('index', { items: data });
});
// 새로운 게시글 생성 (POST 요청 처리)
app.post('/create', (req, res) => {
// 클라이언트로부터 전달받은 제목과 설명으로 새 newItem 객체를 만듭니다.
const newItem = {
id: Date.now(), // 현재 시간을 고유 ID로 사용합니다.
title: req.body.title, // 요청 본문에서 제목을 가져옵니다.
description: req.body.description, // 요청 본문에서 설명을 가져옵니다.
};
// 새 게시글을 `data` 배열에 추가합니다.
data.push(newItem);
// 업데이트된 데이터를 'data.json' 파일에 저장합니다.
fs.writeFileSync('./data.json', JSON.stringify(data, null, 2));
// 작업 완료 후 메인 페이지로 리다이렉트합니다.
res.redirect('/');
});
// 게시글 수정 (POST 요청 처리)
app.post('/edit/:id', (req, res) => {
// URL에서 전달된 ID로 수정할 게시글을 찾습니다.
const index = data.findIndex(d => d.id == req.params.id);
// 게시글이 존재하면 데이터를 업데이트합니다.
if (index !== -1) {
data[index].title = req.body.title; // 요청 본문에서 새로운 제목을 가져와 업데이트합니다.
data[index].description = req.body.description; // 새로운 설명으로 업데이트합니다.
// 업데이트된 데이터를 'data.json' 파일에 저장합니다.
fs.writeFileSync('./data.json', JSON.stringify(data, null, 2));
}
// 작업 완료 후 메인 페이지로 리다이렉트합니다.
res.redirect('/');
});
// 게시글 삭제 (POST 요청 처리)
app.post('/delete/:id', (req, res) => {
// URL에서 전달된 ID를 제외한 게시글만 남깁니다.
data = data.filter(d => d.id != req.params.id);
// 업데이트된 데이터를 'data.json' 파일에 저장합니다.
fs.writeFileSync('./data.json', JSON.stringify(data, null, 2));
// 작업 완료 후 메인 페이지로 리다이렉트합니다.
res.redirect('/');
});
// -------------------- 서버 시작 --------------------
// 서버를 지정된 포트에서 실행합니다.
app.listen(PORT, () => {
console.log(`Server running at http://localhost:${PORT}`);
});
주석 설명 요약
- 모듈: 각종 모듈의 역할과 사용 방법을 설명.
- Middleware: 데이터를 처리하고, 템플릿 엔진을 설정하는 중간 처리 과정 설명.
- Load Data: 파일에서 데이터를 읽어오는 과정 설명.
- Routes: 각 경로(GET, POST 등)의 목적과 주요 로직 설명.
- Start Server: 서버를 시작하고 사용자가 접근 가능한 URL 출력.
'개인 공부 설명 모음' 카테고리의 다른 글
| 윈도우/리눅스 curl 명령어 (0) | 2026.06.03 |
|---|---|
| 정보의 표현 - 1 (0) | 2025.03.06 |
| 컴퓨터 입문 (2) | 2025.03.06 |
| Python 리스트, 튜플, 딕셔너리, 집합 등 기본 자료구조 실습 (0) | 2024.11.17 |
| 변수 Python (1) | 2024.11.17 |