npx create-next-app@latest board --js --tailwind --eslint --app --src-dir --import-alias "@/*"| 옵션 | 의미 |
|---|---|
npx |
도구를 임시로 실행 (설치 안 함) |
create-next-app@latest |
Next.js 프로젝트 생성 도구 (최신 버전) |
board |
프로젝트 폴더 이름 |
--js |
JavaScript 사용 (TypeScript 아님) |
--tailwind |
Tailwind CSS 포함 |
--eslint |
ESLint 포함 (코드 규칙 검사 도구) |
--app |
App Router 사용 (Next.js의 라우팅 방식) |
--src-dir |
src/ 폴더 구조 사용 |
--import-alias "@/*" |
@/로 src 폴더를 참조할 수 있게 설정 |
생성된 폴더 구조:
board/
├── src/
│ └── app/
│ ├── layout.js ← 전체 페이지 틀 (HTML 구조)
│ ├── page.js ← 메인 페이지 (화면에 보이는 내용)
│ └── globals.css ← 전역 스타일
├── package.json ← 프로젝트 정보 + 설치된 패키지 목록
└── ...
git branch chore/VEASLY-365-nextjs-프로젝트-생성 # 브랜치 생성
git checkout chore/VEASLY-365-nextjs-프로젝트-생성 # 브랜치 전환| 명령어 | 의미 |
|---|---|
git branch 이름 |
새 브랜치 생성 (전환은 안 함) |
git checkout 이름 |
해당 브랜치로 전환 |
git checkout -b 이름 |
생성 + 전환을 한 번에 |
// 변경 전
export const metadata = {
title: "Create Next App",
description: "Generated by create next app",
};
// 변경 후
export const metadata = {
title: "Board",
description: "게시판",
};설명:
metadata— 브라우저 탭 제목(title)과 검색엔진 설명(description)을 설정export const— 이 변수를 다른 파일(Next.js 시스템)에서 사용할 수 있게 내보냄
// 변경 전
import { Geist, Geist_Mono } from "next/font/google";
const geist = Geist({ ... });
const geistMono = Geist_Mono({ ... });
// 변경 후
// (삭제함 — 기본 폰트 사용)설명:
import— 다른 파일/패키지에서 기능을 가져오는 문법- Geist 폰트는 Next.js가 기본으로 넣어준 샘플이라 제거
// 변경 전: Next.js 로고, 안내 문구 등 샘플 코드
// 변경 후: 깔끔한 빈 페이지/* 변경 전: 다크모드 블록 포함 */
@media (prefers-color-scheme: dark) {
:root {
--background: #0a0a0a;
--foreground: #ededed;
}
}
/* 변경 후: 다크모드 블록 삭제 */설명:
--background— CSS 변수, 배경색--foreground— CSS 변수, 글자색@media (prefers-color-scheme: dark)— 사용자 기기가 다크모드일 때 적용되는 스타일
git add src/app/layout.js src/app/page.js # 스테이징 (커밋할 파일 선택)
git commit -m "[VEASLY-367] 보일러플레이트 정리" # 커밋 (변경 이력 저장)| 명령어 | 의미 |
|---|---|
git add 파일 |
커밋에 포함할 파일을 선택 (스테이징) |
git commit -m "메시지" |
선택된 파일들을 메시지와 함께 저장 |
-m |
message의 약자, 커밋 메시지를 바로 입력 |
git add src/app/globals.css
git commit -m "[VEASLY-367] 다크모드 보일러플레이트 제거"새 브랜치 생성:
git checkout main # main으로 전환
git merge chore/VEASLY-365-nextjs-프로젝트-생성 # 이전 작업을 main에 합침
git checkout -b feature/VEASLY-389-메인보드-UI생성 # 새 브랜치 생성 + 전환"use client";
import { useState } from "react";
export default function Home() {
const [memos, setMemos] = useState([]);
const [input, setInput] = useState("");
const [editingId, setEditingId] = useState(null);
const [editingText, setEditingText] = useState("");
const addMemo = () => {
if (!input.trim()) return;
setMemos([...memos, { id: Date.now(), text: input }]);
setInput("");
};
const deleteMemo = (id) => {
setMemos(memos.filter((memo) => memo.id !== id));
};
const startEdit = (memo) => {
setEditingId(memo.id);
setEditingText(memo.text);
};
const saveEdit = (id) => {
setMemos(
memos.map((memo) =>
memo.id === id ? { ...memo, text: editingText } : memo
)
);
setEditingId(null);
setEditingText("");
};
const cancelEdit = () => {
setEditingId(null);
setEditingText("");
};
return (
<div className="max-w-xl mx-auto p-6">
<h1 className="text-2xl font-bold mb-6">게시판</h1>
<div className="flex gap-2 mb-6">
<input
type="text"
value={input}
onChange={(e) => setInput(e.target.value)}
placeholder="내용을 입력하세요"
className="flex-1 border border-gray-300 rounded px-3 py-2"
/>
<button
onClick={addMemo}
className="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600"
>
추가
</button>
</div>
<ul className="space-y-2">
{memos.map((memo) => (
<li key={memo.id} className="flex items-center gap-2 border border-gray-200 rounded px-3 py-2">
{editingId === memo.id ? (
<>
<input
type="text"
value={editingText}
onChange={(e) => setEditingText(e.target.value)}
className="flex-1 border border-gray-300 rounded px-2 py-1"
/>
<button onClick={() => saveEdit(memo.id)} className="text-green-600 hover:text-green-800">저장</button>
<button onClick={cancelEdit} className="text-gray-500 hover:text-gray-700">취소</button>
</>
) : (
<>
<span className="flex-1">{memo.text}</span>
<button onClick={() => startEdit(memo)} className="text-blue-500 hover:text-blue-700">수정</button>
<button onClick={() => deleteMemo(memo.id)} className="text-red-500 hover:text-red-700">삭제</button>
</>
)}
</li>
))}
</ul>
</div>
);
}1. 선언부
"use client";- Next.js에게 "이 파일은 브라우저에서 실행해라"라고 알려줌
useState같은 React 기능을 쓰려면 필수
import { useState } from "react";- React 라이브러리에서
useState기능을 가져옴 { }안에 이름을 적어서 필요한 것만 가져오는 문법 (named import)
2. 함수 정의
export default function Home() {function Home()— 페이지를 그리는 함수export default— Next.js가 이 함수를 페이지로 사용할 수 있게 내보냄
3. State (상태 관리)
const [memos, setMemos] = useState([]); // 메모 목록
const [input, setInput] = useState(""); // 입력창 텍스트
const [editingId, setEditingId] = useState(null); // 수정 중인 메모 id
const [editingText, setEditingText] = useState(""); // 수정 중인 텍스트useState(초기값)— 값을 저장하고, 바뀌면 화면을 다시 그림[현재값, 변경함수]— 읽기용과 쓰기용이 항상 쌍으로 나옴[]— 빈 배열,""— 빈 문자열,null— 값 없음
4. 함수들
| 함수 | 역할 | 핵심 문법 |
|---|---|---|
addMemo |
메모 추가 | [...기존, 새것] — 스프레드로 배열 합치기 |
deleteMemo |
메모 삭제 | .filter() — 조건에 맞는 것만 남기기 |
startEdit |
수정 시작 | state에 수정 대상 정보 저장 |
saveEdit |
수정 저장 | .map() + 삼항연산자로 해당 메모만 교체 |
cancelEdit |
수정 취소 | state 초기화 |
5. JSX (화면)
| 문법 | 의미 |
|---|---|
<div className="..."> |
HTML의 class 대신 className 사용 (JSX 규칙) |
{변수} |
JavaScript 값을 화면에 표시 |
{조건 ? A : B} |
삼항연산자 — 조건이 true면 A, false면 B |
{배열.map((item) => ...)} |
배열을 돌면서 각 항목을 JSX로 변환 |
<> </> |
Fragment — 여러 요소를 감싸는 빈 껍데기 |
onClick={함수} |
클릭 이벤트 연결 |
onChange={(e) => ...} |
입력 이벤트 연결, e.target.value로 입력값 가져옴 |
git add src/app/page.js
git commit -m "[VEASLY-389] 메모 보드 CRUD UI 구현"
git add src/app/page.js
git commit -m "[VEASLY-389] Tailwind CSS 스타일링 적용"
git checkout main
git merge feature/VEASLY-389-메인보드-UI생성| 명령어 | 의미 |
|---|---|
git branch |
브랜치 목록 보기 |
git branch 이름 |
새 브랜치 생성 |
git branch -m 이름 |
현재 브랜치 이름 변경 |
git checkout 이름 |
브랜치 전환 |
git checkout -b 이름 |
생성 + 전환 동시에 |
git status |
현재 상태 확인 (스테이징 여부 등) |
git add 파일 |
스테이징 (커밋할 파일 선택) |
git commit -m "메시지" |
커밋 (변경 이력 저장) |
git commit --amend -m "메시지" |
마지막 커밋 메시지 수정 |
git merge 브랜치 |
다른 브랜치를 현재 브랜치에 합침 |
git log |
커밋 이력 보기 |
티켓 생성 → 브랜치 생성 → 작업 → 커밋 → PR → 코드 리뷰 → main에 머지
| 접두어 | 용도 | 예시 |
|---|---|---|
feature/ |
새로운 기능 추가 | feature/BOARD-1-게시판-목록 |
fix/ |
버그 수정 | fix/BOARD-5-로그인-오류 |
hotfix/ |
긴급 버그 수정 | hotfix/BOARD-10-결제-실패 |
refactor/ |
기능 변경 없이 코드 개선 | refactor/BOARD-7-API-정리 |
chore/ |
설정, 세팅 등 잡무 | chore/BOARD-3-eslint-설정 |
main (항상 배포 가능한 안정된 코드)
├── feature/게시판-목록 → 작업 완료 → PR → main에 머지
├── feature/게시글-작성 → 작업 완료 → PR → main에 머지
└── fix/로그인-오류 → 작업 완료 → PR → main에 머지
[VEASLY-365] Next.js + Tailwind 프로젝트 초기 셋업, Nest.js + Prisma + PostgreSQL 초기 셋업
├── [VEASLY-367] Next.js 16 App Router 프로젝트 생성 ✅
├── [VEASLY-387] Nest.js + Prisma + PostgreSQL 세팅 (다음 작업)
└── [VEASLY-389] 메인보드 UI 작업 ✅