FSD 패턴이란?

Jinmin Kim·2025년 9월 3일

FSD

FSD 방향성

FSD의 기본 규칙은 상위 레이어가 “같은 레벨 또는 아래 레이어”에 의존할 수 있다는 것(역참조 금지)입니다.

  • 즉, pages → {widgets, features, entities, shared} 모두 직접 import 가능 (다만 “주로” widgets/조립 위주 권장)
  • widgets → {features, entities, shared}
  • features → {entities, shared} => C,U,(R),D
  • entities → {shared} => C,U,(R),D
  • shared → (없음)

왜 이렇게 되어 있나? (핵심 원리)

  • *레이어는 “책임의 높낮이”**를 나타냅니다. 위로 갈수록 “화면 조립·앱 초기화”, 아래로 갈수록 “도메인 모델·순수 재사용 조각”.
  • 의존 방향은 위 → 아래만 허용합니다. 이렇게 하면 순환 참조·내부 구현 누수를 막고, 대규모 변경에도 영향 범위를 통제할 수 있어요.
  • 다만 실무에선 편의/단순성을 위해 pages가 features를 직접 조립하는 경우가 많습니다. “항상 widgets를 경유해야만 한다”는 규칙은 아닙니다.

레이어별 “무엇을 주로 import하나?”

  • pages
    • 주로: widgets (큰 블록 조립)
    • 가끔: features (페이지가 단촐할 때), entities의 타입/단순 뷰(지양), shared UI
    • 지양: 페이지에서 도메인 상태/비즈니스 로직을 소유
  • widgets
    • 주로: features 묶기 + 일부 entities 뷰/상태
    • OK: shared (공통 UI/유틸)
  • features
    • 주로: entities(도메인 상태/쿼리) 사용하여 “사용자 가치 있는 기능(검색/편집/폼)” 완성
    • OK: shared
  • entities
    • 주로: shared (유틸/공통 API 클라이언트)
    • 지양: 위 레이어 참조
  • shared
    • 완전 중립: 도메인 지식 없음 (Button, Modal, 포맷터 등)

요점: 가능(Allowed) 과 권장(Preferred) 을 구분하세요.

  • 가능: 상위 → 어떤 하위든 import.
  • 권장: 가까운 레이어를 먼저 조합(pages → widgets 중심), 필요할 때만 더 아래로 “직통”.

Public API(배럴) 원칙은 그대로

  • 어느 레이어에서 import하든 항상 해당 Slice의 index.ts(Public API)만 사용하세요.
    • 예) import { useAccount } from '@/entities/account';
    • 예) import { useAccount } from '@/entities/account/api/queries'; ⛔ (내부 경로 직행 금지)

이유
1. 경계 유지: 내부 구현 교체 자유
2. 번들 최소화: 공개된 심볼만 노출
3. 리뷰/린트 자동화: 규칙화 쉬움

FSD 구조

레이어 계층: app → pages → widgets → features → entities → shared

src/
├─ app/                    # 앱 엔트리/프로바이더/라우팅
├─ pages/
│  ├─ main/                # 페이지는 합성만! (비즈니스 로직 없음)
│  │  └─ index.tsx        # widgets/features를 조립
│  └─ sub-main/
├─ widgets/
│  └─ main-dashboard/      # 대형 UI 블록(여러 features를 묶어 페이지에 올림)
│     ├─ ui/
│     ├─ model/
│     ├─ lib/
│     ├─ api/
│     └─ index.ts          # <- Public API
├─ features/
│  ├─ search-projects/  => Slices(Domain)
│  │  ├─ ui/			=> Segments(역활)
│  │  ├─ model/         => Segments(역활)   # (Zustand store/selectors)
│  │  ├─ api/           => Segments(역활)   # (TanStack Query v5 hooks)
│  │  ├─ lib/			=> Segments(역활)
│  │  └─ index.ts
│  └─ edit-project/     => Slices(Domain)
├─ entities/
│  ├─ project/
│  │  ├─ ui/
│  │  ├─ model/            # (도메인 상태/타입, 정적 셀렉터)
│  │  ├─ api/              # (도메인 단위 fetchers)
│  │  ├─ types/
│  │  └─ index.ts
│  └─ user/
├─ shared/
│  ├─ ui/                  # Button/Modal 등 순수 재사용 UI
│  │  ├─ button/
│  │  ├─ modal/
│  │  └─ index.ts
│  ├─ lib/                 # 유틸, 포맷터, hooks(도메인 무관)
│  ├─ api/                 # 공통 fetcher, 클라이언트
│  └─ config/

FSD(Feature Sliced Design)

  • 높은 응집도
  • 낮은 결합도 를위한 구조이다.

FSD는 한마디로 아래와 같다.

  • 파일 - 기능 중심으로 폴더구조(설계)
  • Segment - 역활
  • Slices - 도메인

profile
Let's do it developer

0개의 댓글