최근, 진행하는 사이드프로젝트를 FSD
아키텍처로 구성하여 진행하고있는데 만족도가 높아 정리해보려한다.
FSD(Feature-Sliced-Design)는 프론트엔드 애플리케이션을 기능 단위
로 분할하여 관리하는 아키텍처 방법론이다. 약간의 러닝커브가있고 소규모 프로젝트에서 가져가기엔 오버엔지니어링을 유도할 수 있지만, 규모가 커질수록 일관성, 유지보수성, 확장성 등에서 이점을 가져갈수있다고 생각한다.
FSD에서는 위의 그림처럼 3개의 수직구조가 존재하며, 각각 레이어
, 슬라이스
, 세그먼트
로 나타난다. 각 레이어는 다음과 같다. (공식문서 그대로 복붙)
App
- 앱을 실행하는 모든 것 - 라우팅, 진입점, 전역 스타일, 프로바이더.Processes
(더 이상 사용되지 않음)Pages
- 전체 페이지 또는 중첩 라우팅에서 페이지의 주요 부분.Widgets
- 독립적으로 작동하는 대규모 기능 또는 UI 컴포넌트, 보통 하나의 완전한 기능.Features
- 제품 전반에 걸쳐 재사용되는 기능 구현체로, 사용자에게 실질적인 비즈니스 가치를 제공하는 동작.Entities
- 프로젝트가 다루는 비즈니스 엔티티, 예를 들어 user 또는 product.Shared
- 재사용 가능한 기능, 특히 프로젝트/비즈니스의 특성과 분리되어 있을 때여기서 중요한점은 레이어 계층
에선 상위 레이어는 반드시 하위 레이어만 import 할 수 있다는 점이다. 이러한 구조는 코드의 모듈성을 높이고 각 레이어가 명확한 역할을 가질 수 있게 하며, 코드의 복잡도를 줄이고 유지보수를 용이하게 만든다.
또한 슬라이스 계층
에선 반드시 공개API(index.ts)
를 포함해야하며 슬라이스는 직접 import 될 수 없고 공개API(index.ts) 를 통해서만 접근할 수 있다. (barrel export)
아래는 일반적인 폴더구조와 FSD 폴더구조의 스샷이다.
(흔히 볼 수 있는 프론트엔드 폴더구조)
(FSD 폴더 구조)
App
, Shared
레이어를 제외한 Pages
, Wigets
, Features
, Entities
레이어는 세그먼트
계층을 포함하며 다음과 같다.
ui
- ui와 관련된 모든 것 (컴포넌트)api
- 백엔드와 상호작용하는 요소들 - (api, DTO, mapper, react-query ...)model
- 데이터 모델 (schema, type, store, 비즈니스 로직 ...) config
- 슬라이스에서 필요한 설정 및 상수lib
- 슬라이스에서 사용되는 유틸리티 함수FSD
를 도입하면서 가장 고민이 많았던 지점이 widget
, features
, entities
를 어떠한 기준으로 나눠야하며, 어떤 컨벤션으로 작성할지였다. 계속 디벨롭해가며 자리를 잡아가는 FSD이기에 아직까진 자료도 많이 부족하여 생각이 많았지만, 여러 해외 example repository를 봐가며 내 나름대로의 컨벤션을 세워 작업하고있다. (정답이 아님)
간단한 책을 관리하는 List 페이지를 예시로든다.
사용자의 액션
이 담긴 기능을 담당하며, 실제 비즈니스로직을 포함한다.
ex) 책 추가, 책 삭제, 책 선택, 책 검색... 등 (features/add-book ..)
login, signUp과 같은 form 기반 기능도 여기에 포함된다.
비즈니스 로직은 hook을 적극 활용한다.