React 프로젝트를 시작할 때마다 폴더 구조를 어떻게 잡을지 고민이신가요? 컴포넌트, api, hooks 폴더가 점점 늘어나면서 기능 하나 수정하려고 여러 폴더를 헤매는 경험을 해보셨을 겁니다. Feature-Sliced Design(FSD) 아키텍처는 이런 문제를 해결해주는 방법론으로, 기능 단위로 코드를 묶어 유지보수와 확장성을 크게 개선합니다. 실제로 FSD를 도입하면 코드 탐색 시간이 줄고 기능 간 의존성이 낮아져 생산성이 눈에 띄게 향상됩니다.
React 프로젝트에서 FSD 아키텍처가 필요한 이유
전통적인 역할 기반 폴더 구조(components, api, hooks 같은 폴더로 나누는 방식)는 소규모 프로젝트에서는 문제없이 작동합니다. 하지만 프로젝트 규모가 커질수록 단점이 드러납니다. 예를 들어 '장바구니' 기능 하나를 수정하려면 components 폴더에서 UI를 찾고, hooks 폴더에서 상태 로직을 찾고, api 폴더에서 네트워크 요청을 찾아야 합니다. 이렇게 파편화된 코드는 맥락을 추적하기 어렵게 만들고, 유지보수 비용을 증가시킵니다.
FSD는 이런 문제를 '자주 함께 변경되는 코드를 같은 곳에 보관한다'는 Colocation 원칙으로 해결합니다. 기능(Feature) 단위로 슬라이스를 만들어 관련 코드를 한곳에 모으고, 레이어 간 의존성 규칙을 통해 순환 참조나 불필요한 결합을 방지합니다. 결과적으로 개발자는 프로젝트 전체를 완벽히 이해하지 않아도 자신이 맡은 기능만 집중해서 개발할 수 있습니다.
FSD 아키텍처의 3가지 핵심 계층 구조
FSD는 애플리케이션을 레이어(Layer), 슬라이스(Slice), 세그먼트(Segment) 세 가지 요소로 구분합니다. 각 계층은 고유한 책임과 규칙을 가지고 있어 코드를 체계적으로 구성할 수 있게 돕습니다.
레이어 프로젝트의 최상위 디렉터리
레이어는 애플리케이션을 역할별로 나눈 최상위 디렉터리입니다. FSD 공식 문서에서는 최대 7개 레이어를 권장하며, 일반적으로 다음과 같은 구조를 사용합니다.
- app: 애플리케이션 초기화, 라우팅, 전역 스타일, Provider 설정
- processes: 복잡한 비즈니스 프로세스(로그인 플로우, 주문 프로세스 등)
- pages: 라우트 단위의 페이지 컴포넌트
- features: 사용자에게 직접적인 가치를 제공하는 기능(로그인, 장바구니, 검색)
- entities: 비즈니스 엔티티(사용자, 상품, 주문)
- shared: 재사용 가능한 UI 컴포넌트, 유틸리티, API 클라이언트
각 레이어는 상위 레이어만 참조할 수 있다는 중요한 규칙이 있습니다. 예를 들어 features 레이어는 entities나 shared 레이어를 참조할 수 있지만, pages 레이어를 참조할 수 없습니다. 이 규칙 덕분에 의존성 방향이 단방향으로 유지되어 코드의 결합도가 낮아집니다.
슬라이스 비즈니스 도메인별 코드 그룹화
슬라이스는 각 레이어 내에서 비즈니스 도메인이나 기능 단위로 코드를 세분화합니다. 예를 들어 features 레이어 안에는 auth, cart, search 같은 슬라이스가 생깁니다. 중요한 점은 같은 레이어에 있는 슬라이스끼리는 서로 참조할 수 없다는 규칙입니다. features/auth 슬라이스는 features/cart 슬라이스를 직접 임포트할 수 없습니다. 이렇게 하면 각 기능이 독립적으로 개발되고 테스트될 수 있습니다.
세그먼트 슬라이스 내부 역할 분류
세그먼트는 슬라이스 내부에서 코드를 역할에 따라 분류하는 개념입니다. 일반적으로 다음과 같은 세그먼트가 사용됩니다.
- ui: 해당 슬라이스의 UI 컴포넌트
- model: 비즈니스 로직, 상태 관리, 타입 정의
- api: 서버와의 통신 로직
- lib: 유틸리티 함수, 헬퍼
- config: 기능별 설정 값
각 슬라이스는 공개 API를 제공하여 외부에서 필요한 기능만 노출하고 내부 구현은 숨깁니다. 이는 캡슐화 원칙을 자연스럽게 적용하는 방법입니다.
FSD 아키텍처의 장점과 단점, 실제 적용 시 고려사항
FSD는 많은 장점을 제공하지만, 모든 상황에 완벽한 해결책은 아닙니다. 실제 프로젝트에 도입하기 전에 장단점을 명확히 이해하는 것이 중요합니다.
장점
- 높은 응집도와 낮은 결합도: 기능 단위로 코드가 모여 있어 수정 범위가 최소화됩니다. 한 슬라이스의 변경이 다른 슬라이스에 영향을 줄 가능성이 낮습니다.
- 코드 탐색 용이성: 새로운 개발자가 프로젝트에 투입되어도 '이 기능은 어디에 있지?'라는 고민을 덜 할 수 있습니다. 비즈니스 맥락에 따라 폴더가 정리되어 있기 때문입니다.
- 재사용성 자연 분리:
shared레이어에는 범용 코드,features레이어에는 특정 기능 코드가 위치하므로 재사용 범위가 명확해집니다. - 점진적 도입 가능: 이미 진행 중인 프로젝트라도 기존 구조를 유지하면서 새 기능부터 FSD를 적용할 수 있습니다.
단점
- 러닝 커브: 기존 역할 기반 구조에 익숙한 개발자에게는 FSD의 계층 규칙이 생소할 수 있습니다. 팀 전체의 이해와 교육이 필요합니다.
- 초기 오버헤드: 작은 프로젝트에서는 불필요하게 복잡해 보일 수 있습니다. FSD는 규모가 있는 프로젝트에서 진가를 발휘합니다.
- 과도한 세분화 위험: 팀이 규칙을 제대로 이해하지 못하면 불필요하게 많은 슬라이스와 세그먼트가 생길 수 있습니다.
실제 도입 시 권장 사항
FSD를 처음 도입한다면 아래 단계를 따라 점진적으로 적용해보세요.
- 공식 문서 숙지: Feature-Sliced Design 공식 문서를 팀원 모두가 읽고 기본 개념을 이해합니다.
- 파일럿 프로젝트: 작은 규모의 새 기능이나 페이지부터 FSD 구조로 개발해봅니다. 기존 코드는 그대로 두고 새 기능만 적용해도 효과를 체감할 수 있습니다.
- 코드 리뷰 강화: 레이어 간 의존성 규칙이 잘 지켜지는지 리뷰 프로세스에 포함시킵니다. 특히
features레이어 간 참조가 없는지 확인합니다. - 아키텍처 가이드 문서화: 팀만의 규칙과 예외 사항을 문서로 남겨 일관성을 유지합니다.
FAQ FSD 아키텍처 도입 시 자주 묻는 질문
Q. FSD는 React 전용 아키텍처인가요?
FSD는 React에 특화된 방법론이 아니라 Vue, Angular 등 다른 프런트엔드 프레임워크에도 적용 가능합니다. 다만 React 생태계에서 컴포넌트 기반 개발과 잘 맞아 많이 사용되고 있습니다.
Q. 프로젝트 규모가 작은데 FSD를 적용해도 되나요?
작은 프로젝트에서는 전통적인 역할 기반 구조로도 충분합니다. FSD의 장점은 프로젝트가 커질수록 극대화되므로, 처음부터 적용하기보다는 규모가 커질 조짐이 보일 때 도입하는 것이 좋습니다.
Q. 기존 프로젝트에 FSD를 적용하려면 어떻게 시작해야 하나요?
기존 코드를 한 번에 모두 옮기려고 하면 시간이 오래 걸리고 리스크가 큽니다. 새로 추가되는 기능부터 FSD 구조로 개발하고, 기존 코드는 리팩터링이 필요한 영역부터 점진적으로 옮기는 방식을 추천합니다.
Q. shared 레이어에 너무 많은 코드가 몰리지 않을까요?
shared는 진정한 재사용이 가능한 코드만 포함해야 합니다. 특정 기능에 종속된 코드를 shared에 넣지 않도록 주의하고, 필요하다면 공용 유틸리티는 shared/lib, UI 컴포넌트는 shared/ui로 세그먼트를 나누어 관리합니다.