기능 분할 설계 (Feature-Sliced Design, FSD)
대규모 프론트엔드 애플리케이션을 구조화하기 위한 현대적인 아키텍처 방법론인 FSD를 소개합니다.
기능 분할 설계(Feature-Sliced Design, FSD)는 대규모 프론트엔드 애플리케이션을 구조화하기 위한 아키텍처 방법론입니다. 애플리케이션을 기능 단위로 분할하고, 각 기능을 독립적으로 개발, 테스트, 유지보수할 수 있도록 해요.
FSD의 핵심 원칙
- 기능 중심 설계: 애플리케이션을 비즈니스 기능 단위로 구성
- 계층화: 코드를 여러 계층으로 구분하여 관심사 분리
- 단방향 의존성: 상위 계층은 하위 계층에만 의존
- 명시적 공개 인터페이스: 각 모듈은 명확한 공개 API를 통해 상호작용
- 구성 가능성: 작은 단위의 기능을 조합하여 더 큰 기능 구성
레이어 (Layers)
| 레이어 | 역할 | 예시 |
|---|---|---|
| app | 애플리케이션 초기화 및 글로벌 설정 | 라우팅, 전역 상태, 전역 스타일 |
| processes | 복잡한 비즈니스 프로세스 관리 (선택적) | 다단계 체크아웃, 온보딩 |
| pages | 라우팅 가능한 화면 정의 | 홈페이지, 상품 페이지 |
| widgets | 재사용 가능한 UI 블록 | 헤더, 사이드바, 상품 목록 |
| features | 사용자 시나리오와 비즈니스 로직 | 로그인, 장바구니 추가 |
| entities | 도메인 객체와 관련 로직 | 사용자, 상품 |
| shared | 공유 유틸리티 및 UI 키트 | 버튼, API 클라이언트, 설정 |
각 레이어는 하위 레이어에만 의존할 수 있어, 단방향 데이터 흐름을 보장해요.
슬라이스 (Slices)
슬라이스는 각 레이어 내에서 특정 기능 영역이나 도메인을 나타내는 하위 디렉토리예요. 특정 비즈니스 도메인이나 기능을 캡슐화하고, 독립적으로 개발 및 테스트할 수 있습니다.
1
2
3
4
5
6
7
8
src/
features/
auth/ // 인증 관련 슬라이스
product-catalog/ // 상품 목록 관련 슬라이스
shopping-cart/ // 장바구니 관련 슬라이스
entities/
user/ // 사용자 엔티티 슬라이스
product/ // 상품 엔티티 슬라이스
세그먼트 (Segments)
세그먼트는 슬라이스 내부의 코드를 목적에 따라 더 세분화한 것입니다.
| 세그먼트 | 역할 |
|---|---|
| ui | UI 컴포넌트 |
| model | 비즈니스 로직 (상태 관리, 액션, 셀렉터) |
| api | 외부 서비스와의 통신 |
| lib | 유틸리티 함수 |
| config | 설정 및 상수 |
1
2
3
4
5
6
7
8
9
10
features/
auth/
ui/
LoginForm.tsx
RegisterForm.tsx
model/
authSlice.ts
authSelectors.ts
api/
authApi.ts
Public API
각 슬라이스나 세그먼트의 루트에 index.ts 파일을 생성하고, 외부에서 사용할 항목만 명시적으로 export합니다.
1
2
3
4
5
// features/auth/index.ts
export { LoginForm } from './ui/LoginForm';
export { RegisterForm } from './ui/RegisterForm';
export { login, logout } from './model/authSlice';
export { selectUser } from './model/authSelectors';
Public API를 통해 내부 구현을 숨기면, 리팩토링 시 외부에 영향을 주지 않고 내부 구조를 변경할 수 있어요.
프로젝트 구조 예시
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
src/
app/
index.tsx
store.ts
routes.ts
pages/
HomePage/
ProductPage/
widgets/
Header/
Footer/
features/
auth/
product-search/
entities/
user/
product/
shared/
ui/
lib/
페이지는 위젯과 기능을 조합하여 구성해요.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// pages/HomePage/index.tsx
import { Header } from 'widgets/Header';
import { ProductList } from 'widgets/ProductList';
import { ProductSearch } from 'features/product-search';
export const HomePage = () => (
<>
<Header />
<main>
<ProductSearch />
<ProductList />
</main>
</>
);
장점
- 모듈성: 기능 단위로 코드를 구성하여 재사용성과 유지보수성 향상
- 확장성: 새로운 기능 추가나 기존 기능 수정이 용이
- 테스트 용이성: 각 슬라이스와 세그먼트를 독립적으로 테스트 가능
- 팀 협업: 기능 단위로 작업을 분배하여 병렬 개발 가능
- 코드 네비게이션: 일관된 구조로 코드 탐색이 쉬움
적용 시 고려 사항
학습 곡선 팀 전체가 FSD 개념을 이해하고 동의해야 합니다.
오버엔지니어링 주의 작은 프로젝트에서는 복잡도가 증가할 수 있습니다. 프로젝트 규모가 중대형 이상이고, 팀 크기가 3명 이상이며, 장기 유지보수가 예상될 때 적합합니다.
일관성 유지 프로젝트 전반에 걸쳐 FSD 규칙을 일관되게 적용해야 합니다.
리팩토링 비용 기존 프로젝트를 FSD로 전환하는 데 상당한 노력이 필요할 수 있습니다. 전체를 한 번에 변경하기보다는, 새로운 기능부터 FSD를 적용하고 점진적으로 확대하는 것을 권장합니다.


