끄적끄적 코딩
article thumbnail
Published 2025. 3. 28. 02:16
FSD 아키텍처 적용하기 FrontEnd
728x90

서론

프로젝트 규모가 커질수록 폴더 구조와 코드의 의존성이 복잡해집니다. 특히 협업이나 유지보수를 고려해야 하는 상황에서는 기존의 레이어드 아키텍처(Page, Components, Hooks 등)가 한계를 드러냅니다.

이런 문제를 해결하기 위한 대안으로 최근 프론트엔드 커뮤니티에서 FSD(Feature-Sliced Design) 아키텍처가 주목받고 있습니다.


FSD 아키텍처란?

FSD 아키텍처는 Feature-Sliced Design의 약자로, 기능 중심의 프론트엔드 아키텍처 설계 방식입니다. 기존의 레이어 기반 구조와는 달리, 도메인 기반의 기능을 중심으로 코드를 구성함으로써 유지보수성과 확장성을 높일 수 있습니다. 각 계층은 명확한 역할을 가지며, 복잡한 애플리케이션 구조를 더 잘 관리할 수 있도록 돕습니다.

FSD는 구조적으로 세 가지 단계로 나뉩니다: Layer → Slice → Segment입니다.

  • Layer는 앱의 전반적인 구조를 나누는 상위 계층으로, 최대 7개 정도로 제한되며 역할이 명확히 정의됩니다.
  • Slice는 각 Layer 내에서 도메인 혹은 기능 단위로 나뉘는 하위 디렉토리입니다. 예를 들어, user, post, comment와 같이 실제 비즈니스 도메인 단위로 구분됩니다.
  • Segment는 각 Slice 내부를 구성하는 하위 폴더로, 보통 api, model, ui, lib 등으로 구성됩니다. 각 세그먼트는 책임에 따라 코드를 나누고 격리합니다.

FSD는 각 기능이 자체적으로 UI, 상태 관리, API 호출 등을 포함하도록 하여 높은 응집도와 낮은 결합도를 지향합니다. 상위 계층은 하위 계층의 내용을 사용할 수 있지만, 반대로 하위 계층은 상위 계층을 참조할 수 없습니다. 예를 들어 features는 entities나 shared를 사용할 수 있지만, entities는 features에 의존하지 않습니다.

또한, 각 slice나 segment는 Public API(index.ts) 파일을 통해서만 외부로 기능을 노출합니다. 이 방식은 내부 구현을 숨기고, 필요한 기능만 외부에 공개할 수 있어 모듈 간의 의존성을 명확하게 제어할 수 있습니다. import 경로 또한 단순화되어 유지보수와 리팩토링 시 안정성을 높이는 데 기여합니다.

이러한 구조적 규칙과 방향성 덕분에, FSD 아키텍처는 구조적인 혼란 없이 기능을 확장하고 유지보수할 수 있도록 돕습니다.

  • App: 전역 설정, 라우팅, 테마 등 앱 전체를 위한 설정
  • Processes: 여러 feature가 조합된 사용자 플로우 (ex. 로그인 플로우) (현재는 사용하지 않음)
  • Pages: 라우팅 단위의 페이지 (feature, widget으로 구성됨)
  • Widgets: feature를 조합한 UI 블록
  • Features: 독립적인 기능 단위 (ex. 댓글 작성, 좋아요 버튼)
  • Entities: 핵심 도메인 모델 (ex. User, Post)
  • Shared: 공통 컴포넌트, 유틸, 타입 등

왜 프론트엔드에서 FSD 아키텍처가 필요할까?

기존 아키텍처에서는 다음과 같은 문제가 발생하기 쉽습니다:

  • 폴더 구조가 레이어 기준이라 기능별 흐름 파악이 어려움
  • 컴포넌트 간 의존성이 꼬이고, 변경 영향 범위 예측이 어려움
  • 기능 추가 시 다양한 폴더를 넘나들며 수정해야 함

반면, FSD 아키텍처는 기능 단위로 코드를 구성하므로:

  • 기능 단위로 책임이 명확해지고 유지보수가 쉬워짐
  • 새로운 기능을 독립적으로 개발 및 테스트 가능
  • 협업 시 충돌 가능성이 줄어들고, 도메인 단위의 논의가 쉬움

FSD 아키텍처를 적용한 예제들

간단한 게시글 좋아요 기능을 예로 들어보겠습니다. 이 기능을 FSD 아키텍처로 구성하면 다음과 같은 폴더 구조가 됩니다:

src/
├── features/
│   └── like-post/
│       ├── ui/
│       │   └── LikeButton.tsx       // 좋아요 버튼 UI 컴포넌트
│       ├── model/
│       │   └── useLikePost.ts       // 상태 관리 및 훅
│       └── api/
│           └── likePost.ts          // 좋아요 API 요청 함수
  • ui에는 화면에 보여질 컴포넌트를 작성하고,
  • model에서는 훅이나 상태 관리를 담당하며,
  • api에서는 백엔드와 통신하는 로직을 작성합니다.

이 구조의 장점은 하나의 기능이 하나의 폴더 안에 응집되어 있어 이해하기 쉽고, 수정하거나 재사용하기에도 효율적이라는 점입니다.

조금 더 복잡한 예시로는, 게시글 작성과 댓글 기능을 포함한 구조를 생각해볼 수 있습니다. 이때는 여러 계층이 함께 작동하게 됩니다:

src/
├── pages/
│   └── post-create/                // 게시글 작성 페이지
├── widgets/
│   └── post-editor/                // 게시글 작성 에디터 위젯
│   └── comment-section/            // 댓글 목록과 입력란 위젯
├── features/
│   └── create-post/
│       ├── ui/PostForm.tsx         // 게시글 작성 폼 컴포넌트
│       ├── model/usePostForm.ts    // 게시글 작성 상태 관리 훅
│       └── api/createPost.ts       // 게시글 등록 API 요청
│   └── comment/
│       ├── ui/CommentList.tsx      // 댓글 리스트 컴포넌트
│       ├── ui/CommentInput.tsx     // 댓글 입력 컴포넌트
│       ├── model/useComment.ts     // 댓글 상태 관리 훅
│       └── api/fetchComments.ts    // 댓글 불러오기 API 요청
├── entities/
│   └── post/
│       └── model/types.ts          // 게시글 타입 정의
│   └── comment/
│       └── model/types.ts          // 댓글 타입 정의
├── shared/
│   └── ui/Button.tsx               // 프로젝트 전역에서 사용하는 버튼 컴포넌트
│   └── lib/validators.ts           // 공통 유효성 검사 함수

이 예제는 복합적인 기능 구조이며, FSD 아키텍처가 기능과 책임을 어떻게 분리해주는지를 보여줍니다. 기능이 명확하게 나뉘고, 각 레이어가 역할에 따라 잘 조합되기 때문에 확장과 유지보수가 편리해집니다.


마무리

FSD 아키텍처는 프로젝트 구조를 기능 중심으로 개발함으로써 유지보수성과 협업 효율을 높여줍니다. 기능 단위의 응집도 높은 구조를 통해 변경에 유연하게 대응할 수 있으며, 도메인 기반의 사고방식으로 더 명확한 코드 구조를 설계할 수 있습니다.

이러한 특성 덕분에 기능이 많아질수록 복잡도가 높아지는 중대형 프로젝트나, 여러 명이 동시에 기능을 개발하는 협업 환경에서 특히 효과를 발휘합니다. 반면, 규모가 작고 기능이 적은 프로젝트에서는 다소 과한 구조일 수 있으므로, 프로젝트 특성을 고려해 선택하는 것이 좋습니다.

또한 FSD 아키텍처는 모든 계층을 처음부터 적용할 필요는 없습니다. features, shared, pages등 핵심 계층부터 점진적으로 적용해보며 팀과 프로젝트에 맞게 구조를 확장해나가는 것도 좋은 방법입니다.

'FrontEnd' 카테고리의 다른 글

JWT(Json Web Token)  (0) 2025.03.30
웹 페이지 요청부터 렌더링까지의 흐름  (0) 2025.03.29
프론트엔드에 SOLID 적용하기  (0) 2025.03.27
Compression Streams API  (1) 2024.03.18
React 디자인 패턴  (1) 2023.09.07

검색 태그