✈️ FSD (Feature-sliced design) 적용기(1) : 개념 학습

Pyotato·2024년 4월 21일
0

🤯 로드메이커 프로젝트의 구성에 고민을 하던 중, 인프런 멘토링을 통해 FSD라는 아키텍쳐에 대해 멘토님이 말씀해주셨고, 호기심이 발동해서 해당 아키텍쳐를 공부해보고 적용하고자 해봤습니다.
👋 해당 내용은 Feature sliced design을 토대로 공부한 내용과 nextjs(14.1.0 버전) 프로젝트에 적용한 기록을 담았습니다.
👋 학습과 병행한 기록이기 때문에 오류가 있을 수 있습니다. 해당 피드백은 댓글을 남겨주시면 감사하겠습니다.
🗣️ 내용 전달의 간결함을 위해서 이후 내용은 비격식체로 작성되었습니다.

FSD

Feature-Sliced Design (FSD) is an architectural methodology for scaffolding front-end applications. Simply put, it's a compilation of rules and conventions on organizing code. The main purpose of this methodology is to make the project more understandable and structured in the face of ever-changing business requirements.

FSD는 프론트엔드 애플리케이션의 비계(scaffold, 공사현장에서 높은 건물을 짓기 위한 보조 임시구조물) 역할을 하는 아키텍쳐 방법론이다. 간단히 말하자면, 코드를 관리하기 위한 규칙과 컨벤션의 집합이다. 이 방법론의 주 목적은 프로젝트를 더 이해하기 쉽고, 비즈니스적 요구사항의 가변성으로부터 체계적으로 만드는 것이다.

Basics

FSD에 따른 프로젝트 구성

FSD에서 프로젝트는 segment들이 모여 slice를 구성하고, slice들이 모여 layer로 구성된다.

layer

  • layer는 모든 프로젝트에서 표준화되고 수직적으로 정렬된다. 즉, 한 layer의 모듈은 하위의 레이어들의 모듈들과만 상호작용 가능하도록 해야한다. 현재는 7개의 layer가 있다. (1: 최하단, 7: 최상단)
    1. shared : 프로젝트/비즈니스의 상세한 부분과 분리된 재사용 가능한 기능 (UIKit, libs, api 등)
    2. entities : 비즈니스 엔티티 (User, Product, Order)
    3. features : 유저 상호작용, 유저에게 비즈니스 가치를 제공해주는 행위 (SendComent, AddToCart, UsersSearch)
    4. widgets : entities와 features를 의미있는 블록들로 합쳐 구성된 레이어
    5. pages: entities, features, widgets를 구성하는 풀 페이지
    6. process: deprecated 페이지간 복잡한 시나리오를 다루는 레이어 (authentication)
    7. app: 애플리케이션 전체 새팅, 스타일, provider

slices

  • 비즈니스 도메인에 따른 코드 구분하여 논리적으로 관련된 모듈들을 모아둬서 코드베이스를 관리하기 용이하다.
  • Slice(슬라이스)들은 같은 layer의 다른 slice들을 사용할 수 없게 하여 결합도(cohesion)을 높이고 응집도(coupling)을 줄인다.

Segments

  • 각 slice에는 segment(세그멘트)로 구성된다. Segment는 slice의 코드를 기술적 목적에 따라 분리한 작은 모듈이다.
  • 가장 흔한 segment는 ui, model(store, actions), apilib (util/hooks) 등이 있다. 필요에 따라 추가하거나 생략가능하다.
  • API클라이언트가 storage인 경우 (GraphQL, Tanstack Query 등)을 제외하고는 apiconfig을 shared layer에만 두는 것이 권장된다.

예시: 소셜 네트워크 애플리케이션

  • app/: 라우팅, store, global style 등의 세팅 포함

  • pages/: 애플리케이션의 각 페이지의 라우트 컴포넌트 포함, 로직이 거의 제외된 합쳐진 결과물만 존재한다.

  • 애플리케이션 내부에서 뉴스피드의 post card를 살펴보자.

  • widgets/: "assembled" post card 포함 = 백엔드의 호출에 따른 content + 상호작용이 가능한 버튼

  • features/: 카드의 상호작용 (ex. 버튼)과 그 상호작용을 다루는 로직

  • entities/: 카드의 껍데기, content과 상호작용가능한 요소들의 슬롯 포함. post의 작성자를 나타내는 타일도 포함되지만 다른 슬라이스에 있다.

장점

  • Uniformity: 코드는 영향력의 범위(layer), 도메인(slice), 그리고 기술적 목적(segement)에 따라 관리가 되어, 새롭게 접하는 사람들에게 이해하기 쉬운 정형화된 아키텍쳐를 제공한다.
  • Controlled reuse of logic: 각 아키텍쳐의 컴포넌트는 목적과 예상 가능한 의존성 (dependency)을 지닌다. 따라서, DRY 원칙과 적응 가능성간의 균형을 잡아준다.
  • Stability in face of changes and refactoring: 변화와 리펙터링에도 안정성을 지닌다. 특정 layer의 모듈은 같은 layer의 다른 모듈에서 사용 불가능하다. 다른 상위 layer에서도 마찬가지로 사용 불가능하다. 따라서 독립적인 변경이 가능하여 예상치 못한 결과를 방지할 수 있다.

점진적 적용

  • 마이그레이션 가이드
    1. 일반적으로 가장 작은 layer들인 appshared layer의 틀을 먼저 잡아라.
    2. FSD의 규칙과는 어긋나는 의존성이 있더라도 존재하고 있는 모든 UI들을 widgetspages에 배분해보자.
    3. featuresentities를 분리하여, page와 widget을 로직이 들어간 layer에서 순수하게 합성된 layer들로 이루어지도록 점진적으로 분리의 정확성을 늘려가자.
profile
https://pyotato-dev.tistory.com/ 로 이사중 🚚💨🚛💨🚚💨

0개의 댓글

관련 채용 정보