FSD 아키텍처
FSD 아키텍처에 대해 정리한 페이지입니다.
Tags
React, FSD
개요
FSD 아키텍처에 대해 정리한 페이지입니다.
FSD의 개념
Feature-Sliced Design
(FSD) 아키텍처란 프론트엔드 애플리케이션의 유지보수성과 확장성을 높이기 위해 고안된 아키텍처 패턴입니다. 특히 대규모 React 프로젝트에서 효율적인 구조를 제공하며, 비즈니스 기능을 중심으로 수직으로 분할하여 프로젝트를 구성하는 것이 핵심입니다. 이 패턴은 복잡한 애플리케이션을 여러 레이어(Layers)
와 슬라이스(Slices)
로 나누어, 관련된 코드들이 서로 가깝게 위치하게 하고 의존성을 단방향으로 제한함으로써 유지보수성과 확장성을 크게 향상시킵니다.
FSD의 핵심 원칙
FSD 아키텍처의 핵심 원칙은 다음과 같습니다.
기능 단위 분리
애플리케이션을 독립적인 비즈니스 기능 단위로 분할하여 각 기능이 독립적인 모듈처럼 동작하도록 구성합니다. 각 기능 단위에서 관련된 모든 요소(Ex. UI, 상태, API 호출 등)를 함께 관리합니다.
계층 구조
FSD 아키텍처에서는 애플리케이션을 여러 가지 주요 계층으로 나눕니다. 계층별 역할을 명확히 구분하여 모듈 간의 결합도를 줄이고 유지보수를 쉽게 합니다. 예를 들어 공통 로직이나 UI 컴포넌트는
shared
레이어에 분리하여 재사용성을 높입니다.단방향 의존성
하위 계층에서 상위 계층으로의 단방향 의존성을 유지합니다. 예를 들어
shared
계층의 코드가entities
계층을 참조할 수 있지만, 그 반대는 불가능합니다.
FSD의 계층 구조
FSD 아키텍처는 다음과 같은 계층 구조를 갖습니다.
Caution
processes 레이어는 여러 페이지나 기능에 걸친 복잡한 비즈니스 로직을 처리하는 레이어로 현재는 더 이상 사용되지 않습니다.
각 계층 구조에 대해 설명하자면 다음과 같습니다.
레이어 (Layers)
레이어(Layers)
는 FSD 아키텍처에서 최상위 폴더에 해당하며, 레이어는 모든 FSD 프로젝트에서 표준화되어 있습니다. 애플리케이션 내에서 모든 레이어를 사용할 필요는 없지만, 이름과 역할을 명확히 구분하여 사용하는 것이 중요합니다. 각 레이어가 수행하는 역할을 정리하면 다음과 같습니다.
1
2
3
4
5
6
7
src
├── app # 애플리케이션 초기화, 라우팅, 전역 상태 관리 등을 담당하는 레이어입니다.
├── pages # URL 경로에 매핑되는 페이지 컴포넌트를 관리하는 레이어입니다. (Ex. HomePage, SettingsPage 등)
├── widgets # 여러 페이지에서 공용으로 사용하는 독립적인 UI 컴포넌트를 관리하는 레이어입니다. (Ex. Header, Searchbar, Sidebar 등)
├── features # 특정 기능의 로직, UI, API 호출을 포함한 독립 모듈입니다. (Ex. 좋아요 버튼, 글 작성 버튼, 정렬 기능 등)
├── entities # 도메인 모델과 관련된 데이터 처리를 담당하는 레이어입니다. (Ex. user, post 등)
└── shared # 애플리케이션 전반에서 재사용되는 유틸리티, UI 컴포넌트 등을 포함하는 레이어입니다. (Ex. 버튼, 헤더, HTTP 클라이언트 등)
Info.
app과 shared는 다른 레이어들과 달리 슬라이스를 가지지 않으며, 직접 세그먼트로 구성됩니다.
레이어를 다룰 때 중요한 점은, 상위 레이어에서는 하위 레이어를 import할 수 있지만, 하위 레이어에서는 상위 레이어를 import할 수 없다는 점입니다. 예를 들어, features
에서 shared
와 entities
를 import할 수 있지만, shared
에서 상위 레이어(Ex. entities
나 features
)를 import할 수는 없습니다. 즉, 하위 계층에서 상위 계층으로의 단방향 의존성을 유지합니다.
각 레이어에 대해 하위 레이어부터 설명하자면 다음과 같습니다.
shared
어떤 기능에도 속하지 않는, 애플리케이션 전반에 걸쳐 재사용되는 요소를 관리하는 레이어입니다. app
레이어와 마찬가지로 슬라이스를 포함하지 않습니다. 공통적으로 사용되는 유틸리티 함수, UI 컴포넌트, hooks, constants 등을 포함합니다.
1
2
3
4
5
6
7
shared
├── api # API 요청, DTO 등 API 관련 파일
├── config # API URL, 테마 설정 등 환경 설정 파일
├── lib # 외부 라이브러리 Wrapping (Ex. axios 인스턴스, i18n 설정 등)
├── model # 스키마, 인터페이스, 스토어, 비즈니스 로직 등 데이터 모델
├── ui # 재사용 가능한 UI 컴포넌트(Ex. Button, Modal 등)나 레이아웃 파일, 로고 파일 등
├── (...)
entities
애플리케이션의 핵심 도메인(데이터 모델)과 관련된 로직을 관리하는 레이어입니다. 일반적으로 API 호출, 상태 관리, 데이터 모델을 담당합니다.
1
2
3
4
5
6
7
8
9
entities
├── user
| ├── api # user 관련 API
| ├── lib # user 관련 유틸리티 함수
| ├── model # user 관련 상태 (Ex. userStore)
| ├── ui # user 관련 UI 컴포넌트
| └── index.ts
├── post
└── comment
features
사용자의 특정 행동과 상호작용과 관련된 기능을 포함하는 레이어입니다. 하나의 기능에 필요한 모든 요소를 그룹화합니다.
1
2
3
4
5
6
7
8
9
features
├── auth
| ├── api # 로그인/로그아웃 API
| ├── lib # 인증 관련 유틸리티 함수
| ├── model # auth 관련 상태 (Ex. authStore)
| ├── ui # 로그인 폼, OAuth 버튼 등 UI 컴포넌트
| └── index.ts
├── search
├── (...)
widgets
여러 개의 기능들을 조합하여 특정 화면의 일부를 구성하는 역할을 맡은 레이어입니다. 일반적으로 하나의 큰 독립적인 컴포넌트를 정의하는 곳입니다.
1
2
3
4
5
6
7
8
9
widgets
├── sidebar
| ├── api # API 관련 파일
| ├── lib # 유틸리티 함수
| ├── model # 커스텀 훅, 스키마, 타입, 인터페이스, 스토어, 비즈니스 로직 등 데이터 모델
| ├── ui # 사이드바 UI 컴포넌트
| └── index.ts
├── searchbar
├── (...)
pages
애플리케이션의 실제 페이지를 구성하는 레이어입니다. 여러 shared
, entities
, features
, widgets
를 조합하여 화면을 구성합니다.
1
2
3
4
5
6
7
8
9
pages
├── home
| ├── api # 페이지 단위 API 관련 파일
| ├── lib # 홈 페이지 관련 유틸리티 함수
| ├── model # 커스텀 훅, 스키마, 타입, 인터페이스, 스토어, 비즈니스 로직 등 데이터 모델
| ├── ui # 홈 페이지 UI 컴포넌트
| └── index.ts
├── main
├── (...)
app
애플리케이션의 진입점에 해당하며, 애플리케이션 초기화, 라우팅 설정, 전역 상태 관리, 전역 스타일 설정 등을 담당하는 레이어입니다. app
레이어는 shared
와 마찬가지로 슬라이스를 포함하지 않으며 세그먼트만 포함합니다.
슬라이스 (Slices)
슬라이스(Slices)
는 각 레이어 내에서 비즈니스 도메인별로 코드를 분리하는 단위입니다. 슬라이스는 같은 레이어 안에서 다른 슬라이스를 참조할 수 없으며, 이를 통해 높은 응집도와 낮은 결합도를 유지할 수 있습니다.
1
2
3
4
5
6
7
8
9
src
├── features
| ├── auth
| └── search
├── entities
| ├── user
| ├── post
| └── comment
├── (...)
세그먼트 (Segments)
세그먼트(Segments)
는 슬라이스 내부에서 UI, Model, API, 유틸리티 등 역할에 따라 더 세분화하여 관리하는 구조를 의미합니다. 이를 통해 관련된 기능들이 한 곳에 모여 있어 코드의 응집도를 높이고, 불필요한 의존성을 줄일 수 있습니다.
1
2
3
4
5
6
7
[Slice]
├── api # API 요청, DTO 등 API 관련 파일
├── config # 설정 값과 상수 파일
├── lib # 유틸리티 함수
├── model # 커스텀 훅, 스키마, 타입, 인터페이스, 스토어, 비즈니스 로직 등 데이터 모델
├── ui # UI 컴포넌트, 날짜 포맷터, 스타일 등 UI 관련 파일
└── index.ts
Public API
Public API
는 슬라이스나 세그먼트가 애플리케이션의 다른 모듈에서 가져올 수 있는 것을 선언하는 것을 의미합니다. index.js
또는 index.ts
파일을 통해 필요한 파일만 export할 수 있습니다. 이를 통해 외부에서는 index.js
또는 index.ts
파일만 사용하므로 슬라이스 또는 세그먼트 내부 구조에 의존할 필요가 없게 됩니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
src
├── pages
| ├── auth
| | ├── (...)
| | └── index.ts
| └── (...)
|
├── entities
| ├── user
| | ├── (...)
| | └── index.ts
| ├── post
| | ├── (...)
| | └── index.ts
| └── comment
| ├── (...)
| └── index.ts
├── (...)
1
2
3
4
5
6
/* /src/pages/auth/index.ts */
export { LogInPage } from "./ui/LogInPage";
export { RegisterPage } from "./ui/RegisterPage";
(...)
FSD의 장점
FSD 아키텍처의 장점은 다음과 같습니다.
확장성
새로운 기능 추가 시 기존 코드를 최소한으로 수정하며 확장 가능합니다.
유지보수성
기능별로 코드가 명확히 분리되어 있기 때문에 기능 단위로 결합도가 낮습니다. 따라서 특정 기능 수정 시 특정 모듈만 집중해서 수정할 수 있으며 다른 부분에 미치는 영향을 최소화할 수 있습니다.
협업 효율성
팀원들이 각자 다른 기능을 병렬로 개발할 때 충돌 위험이 줄어듭니다.
단방향 의존성
상위 레이어가 하위 레이어에만 의존하도록 설계되어, 코드 변경 시 전반적인 영향을 줄일 수 있습니다.
테스트 용이성
기능 단위로 격리된 테스트가 가능합니다.