Files
frontend/apps/as
..
2026-05-12 14:31:45 +09:00
2026-05-12 14:31:45 +09:00
2026-02-25 14:42:16 +09:00
2026-05-12 15:59:22 +09:00
2026-02-25 14:42:16 +09:00
2026-05-12 14:31:45 +09:00
2026-02-25 14:42:16 +09:00
2026-05-12 14:31:45 +09:00
2026-05-12 14:31:45 +09:00

Template Application

Next.js 애플리케이션 with FSD(Feature Sliced Design) 아키텍처

기술 스택

  • 프레임워크: Next.js 15 + TypeScript
  • 스타일링: Tailwind CSS
  • 상태관리: Zustand
  • 데이터 페칭: TanStack Query (React Query)
  • 폼 관리: React Hook Form + Zod
  • 테이블: TanStack Table
  • HTTP 클라이언트: Axios
  • 날짜 처리: Day.js

프로젝트 구조 (FSD + Next.js App Router)

이 프로젝트는 Feature-Sliced Design v2.1과 FSD 공식 Next.js 가이드에 맞춰 구성되어 있습니다. Next.js app/은 라우트만 담당하고, 실제 레이어는 src/ 아래에 있습니다.

_template/
├── app/                    # Next.js App Router (루트) — 라우트·레이아웃 진입점만
│   ├── layout.tsx         # 루트 레이아웃 (src/app에서 providers, styles import)
│   └── (with-base-layout)/
│       ├── layout.tsx     # BaseLayout 래퍼 (src/app/layouts에서 import)
│       └── page.tsx       # re-export: export { MainPage as default } from '@/pages/home'
│
├── pages/                  # 빈 폴더 + README (Next.js가 src/pages를 Pages Router로 쓰지 않도록)
│   └── README.md
│
└── src/                    # FSD 레이어 (실제 코드)
    ├── app/                # App 레이어 (슬라이스 없음, 세그먼트만)
    │   ├── providers/      # 전역 Providers (QueryClient 등)
    │   ├── styles/         # 글로벌 스타일 (globals.css)
    │   └── layouts/        # 공통 레이아웃 컴포넌트 (BaseLayoutWrapper)
    │
    ├── pages/              # Pages 레이어 (페이지 슬라이스)
    │   └── home/
    │       ├── ui/
    │       └── index.ts    # Public API
    │
    ├── widgets/            # Widgets 레이어
    ├── features/           # Features 레이어
    ├── entities/           # Entities 레이어
    └── shared/             # Shared 레이어
        ├── ui/
        ├── api/
        ├── lib/
        └── config/

계층 구조 이해하기

FSD는 3단계 계층으로 구성됩니다:

  1. Layers (레이어): 책임과 의존성에 따른 수평적 분리 (app, pages, widgets, features, entities, shared)
  2. Slices (슬라이스): 비즈니스 도메인에 따른 수직적 분리 (user, product, auth-login 등)
  3. Segments (세그먼트): 기술적 목적에 따른 분리 (ui, api, model, lib 등)

📚 각 레이어의 자세한 설명은 해당 폴더의 README.md를 참고하세요.

FSD 레이어 설명

FSD는 계층적 아키텍처로, 각 레이어는 책임의 범위와 의존성의 정도에 따라 구분됩니다. 7개의 표준화된 레이어가 있으며, 프로젝트에 필요한 레이어만 사용하면 됩니다.

레이어 계층 구조 (위에서 아래로)

app/       ↑ 가장 높은 책임, 가장 많은 의존성
pages/     |
widgets/   |
features/  |
entities/  |
shared/    ↓ 가장 낮은 책임, 의존성 없음

1. App

  • 목적: 앱 전체에 영향을 주는 기술적/비즈니스적 사항
  • 내용: Context providers, 글로벌 스타일, 스토어 설정, 라우터 설정, 애널리틱스
  • 특징: 슬라이스가 없고 세그먼트로만 구성
  • 의존성: 모든 하위 레이어 사용 가능

2. Pages (src/pages)

  • 목적: 웹사이트나 애플리케이션을 구성하는 페이지/화면
  • 내용: 페이지 UI, 로딩 상태, 에러 바운더리, 데이터 fetching
  • 특징: 한 페이지당 한 슬라이스 (유사한 페이지는 그룹화 가능). Next.js app/의 route 파일에서 re-export
  • 의존성: widgets, features, entities, shared 사용 가능

💡 FSD v2.1 권장사항: "pages-first" 접근 방식을 따라, 재사용되지 않는 큰 UI 블록과 비즈니스 로직은 페이지 슬라이스에 유지하세요.

3. Widgets

  • 목적: 큰 규모의 독립적인 UI 블록
  • 내용: 여러 features와 entities를 조합한 복합 UI
  • 사용 시기: 여러 페이지에서 재사용되거나, 페이지에 여러 개의 큰 독립적 블록이 있을 때
  • 의존성: features, entities, shared 사용 가능 (다른 widgets 불가)

4. Features

  • 목적: 사용자가 수행하는 주요 상호작용과 비즈니스 기능
  • 내용: 사용자 시나리오 (예: 로그인, 상품 검색, 댓글 작성)
  • 사용 시기: 여러 페이지에서 재사용되는 기능
  • 의존성: entities, shared 사용 가능 (다른 features 불가)

5. Entities

  • 목적: 비즈니스가 다루는 실제 개념 (User, Product, Order 등)
  • 내용: 데이터 모델, 타입, API 요청, 엔티티의 시각적 표현
  • 특징: 비즈니스 용어로 명명
  • 의존성: 다른 entities, shared 사용 가능

6. Shared

  • 목적: 애플리케이션의 기반 제공
  • 내용: API 클라이언트, UI Kit, 유틸리티 라이브러리, 글로벌 설정
  • 특징: 비즈니스 로직 없음, 슬라이스가 없고 세그먼트로만 구성
  • 의존성: 외부 라이브러리만 사용 가능 (다른 레이어 불가)

시작하기

# 의존성 설치
pnpm install

# 개발 서버 실행
pnpm run dev

# 프로덕션 빌드
pnpm run build

# 프로덕션 서버 실행
pnpm start

환경 변수

.env.local 파일 생성:

NEXT_PUBLIC_API_URL=http://localhost:3000/api

FSD 핵심 규칙

1. Import 규칙

슬라이스 내의 모듈(파일)은 오직 하위 레이어에 있는 슬라이스만 import할 수 있습니다.

// ✅ 올바른 import (하위 레이어)
// features/auth-login/ui/form.tsx
import { User } from "entities/user";
import { Button } from "shared/ui/button";

// ❌ 잘못된 import (같은 레이어)
// features/auth-login/ui/form.tsx
import { PostForm } from "features/post-create";  // 금지!

// ❌ 잘못된 import (상위 레이어)
// features/auth-login/ui/form.tsx
import { Header } from "widgets/header";  // 금지!

2. Public API 규칙

슬라이스 외부에서는 Public API(index.ts)를 통해서만 접근해야 합니다.

// ✅ 올바른 import (Public API 사용)
import { LoginForm } from "features/auth-login";

// ❌ 잘못된 import (내부 구조 직접 접근)
import { LoginForm } from "features/auth-login/ui/login-form";

Public API 작성 시 주의사항:

  • 와일드카드 re-export(export * from) 사용 지양
  • 필요한 것만 명시적으로 export
  • 슬라이스의 인터페이스를 명확하게 표현
// ❌ 나쁜 예시
export * from "./ui/Comment";
export * from "./model/comments";

// ✅ 좋은 예시
export { Comment } from "./ui/comment";
export { CommentForm } from "./ui/comment-form";
export { useComments } from "./model/use-comments";
export type { Comment, CommentFormData } from "./model/types";