리액트 프로젝트 FSD로 구조 변경 고민 일지

Rachaen·2025년 6월 29일
0

프로젝트 하면서

목록 보기
4/4

서비스를 개발하면서 프로젝트가 커짐에 따라 폴더 구조의 불편함을 느끼게 되어서 구조를 개선하는 과정을 작성해보았습니다.

1. ... 시작 프로젝트 구조

처음 프로젝트를 시작할 때는 React 프로젝트에서 흔히 볼 수 있는 구조로 시작했습니다.

src/
├── 📁 api/          # API 관련 함수들
├── 📁 components/   # 모든 컴포넌트들
├── 📁 constants/    # 상수들
├── 📁 hooks/        # 커스텀 훅들
├── 📁 libs/         # 유틸리티 함수들
├── 📁 pages/        # 페이지 컴포넌트들
├── 📁 routes/       # 라우팅 설정
├── 📁 services/     # 비즈니스 로직
├── 📁 stores/       # 상태 관리
└── 📁 types/        # 타입 정의

점점 느껴지는 문제들..

  1. 높은 결합도(High Coupling)와 낮은 응집도(Low Cohesion)
    가장 큰 문제는 하나의 기능을 구현하려면 여러 폴더를 돌아다녀야 한다는 점이었습니다. 간단한 예를 들자면, 예약 목록 페이지를 수정하려면:

pages/BookingList.tsx - 페이지 컴포넌트
components/BookingCard.tsx - 예약 카드 컴포넌트
hooks/useBooking.ts - 예약 관련 훅
services/bookingService.ts - API 호출 로직
stores/bookingStore.ts - 상태 관리
types/booking.ts - 타입 정의
constants/booking.ts - 상수 정의

무려 7개의 다른 폴더에서 파일을 찾아 수정해야 했습니다.

  1. 컴포넌트 재사용성 판단의 어려움
    components 폴더에는 정말 모든 컴포넌트가 다 들어있었습니다. 공통으로 사용하는 Button 컴포넌트부터 특정 페이지에서만 사용하는 컴포넌트까지... 어떤 컴포넌트가 재사용 가능한지, 어떤 것이 특정 기능 전용인지 구분이 힘들었습니다.

2. 첫번째 시도: 페이지 중심으로 모아보기

문제를 인식하고 나서, 새로 만드는 기능부터는 페이지 폴더 안에 관련 코드를 모아서 관리하기로 했습니다.
(프론트 1인 개발이라 마음대로 해버렸지만 팀에서는 갑자기 이러면 안되겠죠)

새롭게 기능을 추가한 애들
src/
├── 📁 pages/
│   ├── 📁 booking-list/          # 예약 리스트
│   │   ├── 📁 components/
│   │   ├── 📁 api/
│   │   └── 📜 index.ts
│   ├── 📁 mypage/            # 내정보
│   │   ├── 📁 components/
│   │   ├── 📁 api/
│   │   └── 📜 index.ts
├── 📁 routes/
└── 📁 shared/
    ├── 📁 ui/
    ├── 📁 config/
    ├── 📁 api/
    └── 📁 lib/

+ 기존 프로젝트 구조 (레거시)

이렇게 부분적으로 마이그레이션을 진행하니 오히려 더 혼란스러워졌습니다.
어디에 위치해야하지 새로운 구조? 아니면 기존 구조? 기존 코드와 새 코드 간의 공존으로 헷갈리기 시작했습니다.

바쁜 일정에 몇 주동안 이렇게 진행하다가 안되겠다 싶어서 본격적으로 프로젝트 구조 개선을 검토하기로 마음먹었습니다..
그때 발견한 것이 바로 FSD(Feature-Sliced Design) 였습니다. 관련된 것들을 가까이 모아놓는 게 내가 추구하던 방향과 일치해서 FSD를 도입하기로 했습니다.

3. 두 번째 시도: FSD 도입

FSD의 레이어 구조를 참고하여 다음과 같이 재구성하기로 했습니다. (아직 안 함)

src/
├── 📁 app/                  # 앱 초기화
│   ├── 📁 providers/
│   ├── 📁 routes/
│   └── 📁 stores/
├── 📁 pages/                # 페이지
│   ├── 📁 booking-list/     # 예약 목록
│   ├── 📁 mypage/       # 내 정보
│   └── 📁 admin/
│       ├── 📁 meetup-management/
│       ├── 📁 user-management/
│       └── 📁 booking-management/
├── 📁 widgets/              # 큰 UI 블록
│   ├── 📁 header/
│   ├── 📁 meetup-calendar/  # 밋업 캘린더
│   └── 📁 booking-status-board/ # 예약 현황판
├── 📁 features/             # 기능
│   ├── 📁 auth/
│   │   ├── 📁 ui/
│   │   ├── 📁 model/
│   │   └── 📁 api/
│   ├── 📁 create-meetup/    # 밋업 등록
│   ├── 📁 apply-meetup/     # 밋업 신청
│   ├── 📁 cancel-booking/   # 예약 취소
├── 📁 entities/             # 비즈니스 엔티티
│   ├── 📁 user/
│   │   ├── 📁 ui/          # UserCard, UserAvatar
│   │   ├── 📁 model/       # User 타입, 상태
│   │   └── 📁 api/         # getUser, updateUser
│   ├── 📁 booking/
│   │   ├── 📁 ui/          # BookingCard, BookingStatus
│   │   ├── 📁 model/       # Booking 타입, 상태
│   │   └── 📁 api/         # getBooking API
└── 📁 shared/
    ├── 📁 ui/              # Button, Modal, Input 등
    ├── 📁 api/             # API 클라이언트
    └── 📁 lib/             # 날짜, 유틸리티

FSD가 뭐길래?

FSD(Feature-Sliced Design)는 프론트엔드 프로젝트를 위한 아키텍처 설계 방법론입니다. 공식문서에 따르면:

핵심 개념:

  • Layer(레이어): 표준화된 7개 레이어로 구성
    • sharedentitiesfeatureswidgetspagesapp
    • 각 레이어는 특정한 역할과 책임을 가짐
  • Slice(슬라이스): 각 레이어 내의 비즈니스 도메인별 그룹
    • 예: features/auth, entities/user
  • Segment(세그먼트): 슬라이스 내의 기술적 목적별 그룹
    • 표준 세그먼트: ui, model, api, lib, config

중요한 건 관련된 것들을 모아놓고 명확한 경계를 만드는 것이 저의 목표랑 일치했다는 것..

FSD Layers에서 각각 layer의 역할에 대해 보고 FSD Github에서 examples를 보는 것도 추천합니다. examples에서도 7개의 레이어를 모두 사용하진 않더라고요. 일단 저는 초초초초보이기 때문에 7개의 레이어 그대로 가려고요.

디테일한 개념은 프로젝트에 적용하면서 완벽(?)하게 이해했을 때 포스팅을 추가해나가볼까 생각 중입니다.

이제 바꾸러 가볼까... 🥲 먼길이 될 거 같지만 화이팅

profile
개발을 잘하자!

0개의 댓글