지금까지 폴더 구조에 대해 고민해본적 없었다.
개인, 팀프로젝트는 화면상 기능, 뎁스가 깊지 않았고,
인턴 시절엔 이미 폴더 구조가 정해져 있었으니 그에 대해 적응하면 그만이었다.
하지만 실제 서비스 할 제품을 만들면서 부터는 고민이 깊어지기 시작했다.
물론 MVP를 빠른 속도로 개발 하는 것이 1순위라 생각했지만,
아예 무시하고 개발하기엔 이후에 발생할 유지보수비용이 너무나 커질 것만 같았다.
그래서 찾아본게
Feature-Sliced Design
FSD 아키텍쳐이다.
기존엔 레이어, 도메인 기반으로만 코드를 나누고 있었다.
import Logo from '../../../../../../../assets/logo.png';
src/components/common/
└── TokenListCard.tsx # ❌ 특정 페이지에서만 쓰는 컴포넌트
src/pages/exchange/...
src/pages/add/exchange/...
이런 문제들을 해결할 수 있는 아키텍쳐라 본다.
기능단위로 프로젝트를 분할, 각 계층에서 책임을 분리
모든 FSD 프로젝트의 표준 최상위 폴더
src/
├── app/ # 애플리케이션 로직이 초기화되는 곳입니다. 프로바이더, 라우터, 전역 스타일 등 정의. 애플리케이션의 진입점 역할.
├── processes/ # 온보딩, 회원가입과 같이 한 기능에 여러 페이지(더이상 안쓰임)
├── pages/ # 애플리케이션의 페이지
├── widgets/ # 페이지에 사용되는 독립적인 UI 컴포넌트
├── features/ # (선택적) 비즈니스 가치를 전달하는 사용자 시나리오와 기능(좋아요, 리뷰 작성, 제품 평가 등).
├── entities/ # (선택적) 사용자, 리뷰, 댓글 등
└── shared/ # 로직에 종속되지 않은 재사용 가능한 컴포넌트와 유틸리티(UI 키트, axios 설정, 애플리케이션 설정, 비즈니스 로직)
Layer 내부를 비즈니스 도메인별로 나눈 두 번째 수준.
src/
├── app/
│ ├── providers/
│ ├── styles/
│ └── index.tsx
├── pages/
│ ├── home/
│ ├── profile/
│ └── about/
├── widgets/
│ ├── newsfeed/
│ ├── catalog/
│ ├── header/
│ └── footer/
├── features/
│ ├── user/
│ ├── auth/
│ ├── favorites/
│ └── filter-users/
├── entities/
│ ├── user/
│ └── session/
└── shared/
Slice와 App·Shared Layer는 Segment로 세분화
ui - UI components, date formatter, styles 등 UI 표현과 직접 관련된 코드
api - request functions, data types, mappers 등 백엔드 통신 및 데이터 로직
model - schema, interfaces, store, business logic 등 애플리케이션 도메인 모델
lib - 해당 Slice에서 여러 모듈이 함께 사용하는 공통 library code
config - configuration files, feature flags 등 환경·기능 설정
리팩토링 중에는 새로운 대규모 Entity 추가를 피하는 것을 추천.
위 과정에서 FSD 규칙을 위반은 괜찮음.
정답은 없다.
다만, 오답은 있다.
오죽 했으면 리액트 공식 문서에서 조차 폴더 아키텍쳐에 대해서 별 다른 의견이 없다고 하겠는가?
하지만 오답은 있다.
너무나 많은 중첩, 너무 높은 의존도, 이에 대한 너무 많은 생각과 고민은 피하라고 한다.
효율적이라 생각는 방법이 다른 사람들을 납득시킬 수 있으면
그게 정답이지 않을까?