1 분 소요

Feature-Sliced Design (FSD)

Layers, Slices, Segment 폴더로 구분하고 Depth를 3으로 제한한다.

Layers

레이어는 모든 FSD 프로젝트에서 표준화되어 있다. 모든 레이어를 사용할 필요는 없지만, 이름은 중요하다.

  • app
    • 애플리케이션 로직이 초기화되는 곳. provider, router, 전역 스타일, 전역 타입 선언 등이 정의된다. 애플리케이션의 진입점 역할.
  • pages
    • 애플리케이션의 페이지가 포함된다. (브라우저 주소 단위의 컴포넌트)
  • Widgets
    • 독립적으로 작동하는 대규모 기능 또는 UI 컴포넌트, 보통 하나의 완전한 기능.
  • entities
    • 비즈니스 로직을 담는 핵심적인 데이터 모델 (도메인 단위로 구성). 특정 도메인의 데이터 모델을 정의하고, API 호출 같은 기본적인 동작을 담당
  • Features
    • 사용자의 특정 기능을 담당하는 단위. Entities를 조합하여, 사용자가 직접 실행하는 기능(검색, 로그인, 필터링 등)을 제공. 도메인과 무관.
  • shared
    • 해당 레이어에는 특정 비즈니스 로직에 종속되지 않은 재사용 가능한 컴포넌트와 유틸리티가 포함되어 있다. 전역으로 사용하는 컴포넌트, 인터셉터, type, 애플리케이션 설정 등이 포함되어 있다.

Slices

비즈니스 도메인별로 코드를 분할한다. 자유롭게 네이밍을 할 수 있다. 슬라이스는 논리적으로 관련된 모듈들을 가까이 유지함으로써 코드베이스를 더 쉽게 탐색할 수 있게 해준다. 슬라이스는 같은 레이어 안에서 다른 슬라이스를 참조할 수 없으며, 이 규칙은 높은 응집도와 낮은 결합도를 유지하는 데 도움이 된다.

// ❌ features/auth에서 features/profile을 직접 참조 (위반)
import { ProfileCard } from "@/features/profile/ui";

export const Login = () => {
  return (
    <div>
      <button>로그인</button>
      <ProfileCard /> {/* 다른 슬라이스 직접 참조 (위반) */}
    </div>
  );
};

공통 요소는 shared/에 둬야한다.

Segment

전체 Slices와 2개의 App, Shared 레이어는 세그먼트로 구성되며, 세그먼트는 목적에 따라 코드를 그룹화한다. 세그먼트 이름은 표준에 의해 제한되지 않지만, 가장 일반적인 목적을 위한 몇 가지 관례적인 이름이 있다.

  • ui - UI와 관련된 모든 것: UI 컴포넌트, 날짜 포맷터, 스타일 등.
  • api - 백엔드 상호작용: request 함수, 데이터 타입, mapper 등.
  • model - 데이터 모델: 스키마, 인터페이스, 스토어, 비즈니스 로직.
  • lib - 슬라이스 안에 있는 다른 모듈이 필요로 하는 라이브러리 코드.
  • config - 설정 파일과 기능 플래그.

정리

Layers는 네이밍이 정해져 있으며, Slices는 사용한 도메인 별로 코드를 분할한다. Segment는 주로 5개의 네이밍을 사용하여 목적에 따라 코드를 그룹화 한다. 꼭 이를 지켜야 하는 것은 아니고, 참고하여 목적에 맞는 디자인 패턴으로 변형하여 프로젝트에 사용하면 된다.

카테고리:

업데이트: