과제 기반 프로젝트로, 각 과제별로 독립적인 기능을 구현합니다.
- Language: JavaScript, TypeScript
- Framework: Next.js 16.0.8 (App Router)
- UI Library: React 19.2.1
- Data Fetching: React Query (TanStack Query)
- State Management: Jotai
- Form Management: React Hook Form
- CSS-in-JS: Emotion (@emotion/react, @emotion/styled)
- Code Quality: ESLint, Prettier
- Git Hooks: Husky, lint-staged
- Network: Fetch API (Browser Native)
src/
app/
(features)/ # 라우트 그룹 (선택적)
list-pagination/ # 피쳐: 페이지네이션 목록 페이지
page.tsx # 페이지 컴포넌트
components/ # 해당 페이지 전용 컴포넌트
hooks/ # 해당 페이지 전용 커스텀 훅
api/ # 해당 페이지 전용 API 호출
types.ts # 해당 페이지 전용 타입 정의
list-infinite/ # 피쳐: 무한스크롤 목록 페이지
search-with-submit/ # 피쳐: 검색 (submit 버튼)
search-without-submit/ # 피쳐: 검색 (debounce)
layout.tsx # 루트 레이아웃
page.tsx # 홈 페이지 (피쳐 목록)
error.tsx # 전역 에러 처리
global-error.tsx # 루트 레이아웃 에러 처리
not-found.tsx # 404 에러 처리
globals.css # 전역 스타일
shared/ # 공통 사용
components/ # 공통 컴포넌트
ErrorBoundary.tsx
AsyncBoundary.tsx
search/ # 검색 관련 공통 컴포넌트
SearchInput.tsx
SearchResultContainer.tsx
# ... 기타 공용 컴포넌트
hooks/ # 공통 커스텀 훅
useDebounce.ts
useSearchPosts.ts
utils/ # 유틸 함수
types/ # 공통 타입 정의
constants/ # 상수
api/ # 공통 API 클라이언트
client.ts
search.ts # 검색 API 함수
- 피쳐 기반 구조: 각 과제가 독립적인 피쳐로 관리됨
- 피쳐별 독립성: 피쳐 간 직접 의존 금지,
shared/를 통해서만 공통 기능 사용 - Server/Client 구분: Server Components를 기본으로 사용, 필요 시에만 Client Components
- 공통 기능 재사용: 2개 이상의 피쳐에서 사용하는 것은
shared/에 배치
- Server Components: 기본
fetch사용 (Next.js가 자동으로 Suspense와 통합) - Client Components: React Query 사용 (페이지네이션, 무한스크롤, 검색 등)
- API 클라이언트: 커스텀 API 클라이언트 래퍼 사용 (fetch 기반)
다층적 에러 방어 전략
-
React Query 전역 에러 핸들러
QueryCache레벨에서 에러 감지 및 로깅- 개발 환경에서 상세 에러 로그 출력
-
Next.js 예외 처리 파일 시스템
app/error.tsx: 페이지 및 레이아웃 레벨 에러 처리 (Server/Client Components 모두 지원)app/global-error.tsx: Root Layout 에러 처리 (최후 방어선)app/not-found.tsx: 404 에러 처리
-
ErrorBoundary (보조적 사용)
- 특정 클라이언트 컴포넌트 트리의 에러 격리
- 복잡한 위젯, 차트 등 독립적인 피쳐 섹션에서 사용
- Emotion: CSS-in-JS 라이브러리 사용
- 테마 시스템: CSS 변수 기반 테마 관리 (Server Components 호환성)
- Server Components: Emotion 사용 불가, 전역 CSS 또는 기본 스타일 사용
- Client Components: Emotion의
cssprop 사용,theme객체로 테마 접근
First, run the development server:
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun devOpen http://localhost:3000 with your browser to see the result.
홈 페이지에서 각 피쳐(페이지네이션, 무한스크롤, 검색 등)로 이동할 수 있습니다.
This project uses next/font to automatically optimize and load Geist, a new font family for Vercel.
- 포매팅: Prettier 사용 (자동 포매팅)
- 린팅: ESLint 사용 (자동 수정)
- 커밋 전: Husky + lint-staged로 자동 검사
- Server Components: 기본으로 사용 (성능, SEO 최적화)
- Client Components: 인터랙션이 필요한 경우에만 사용 (
'use client'지시어) - 스타일링: Emotion 사용 (Client Components에서만)
- 공통 클라이언트:
shared/api/client.ts의apiClient사용 - 피쳐별 API:
app/{feature-name}/api/에 배치 - 타입 안정성: 모든 API 함수에 타입 정의
사용 예시:
// 피쳐별 API 함수
// app/list-pagination/api/products.ts
import { apiClient } from '@/shared/api/client';
interface Product {
id: number;
name: string;
}
export async function getProducts(page: number): Promise<Product[]> {
return apiClient.get<Product[]>(`/api/products?page=${page}`);
}에러 처리:
import { ApiError } from '@/shared/api/types';
try {
const products = await getProducts(1);
} catch (error) {
if (error instanceof ApiError) {
console.error(`API Error: ${error.status} - ${error.message}`);
console.error('Error data:', error.data);
}
}환경 변수 설정:
.env.local 파일에 다음을 추가:
NEXT_PUBLIC_API_URL=http://localhost:3000/api기본값은 http://localhost:3000/api입니다.
프로젝트의 아키텍처 결정사항은 의사결정 문서에서 확인할 수 있습니다.
To learn more about Next.js, take a look at the following resources:
- Next.js Documentation - learn about Next.js features and API.
- Learn Next.js - an interactive Next.js tutorial.