개발 기록 남기기✍️

Feature Sliced Design 그게 뭔데.. 본문

Front-End/기초 지식

Feature Sliced Design 그게 뭔데..

너해동물원 2025. 3. 1. 22:02

빠르다 빨라 프론트엔드 개발 트렌드! ⏰

최근 들어서 Feature Sliced Design(a.k.a FSD)라는 아키텍처가 뜨는 추세인 것 같은데.. 매번 봐도 봐도.. 헷갈린단 말임..?

FSD의 개념에 대해 확실하게 정리하고, 요걸 Next.js 프로젝트에 어떻게 적용할 수 있을지를 정리하고자 합니다.

 

🤔 그래서 FSD 그게 뭔데 씹덕아

 

공식문서를 한 번 봐봅시다.

 

Overview | Feature-Sliced Design

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

feature-sliced.design

 

💡 기능 분할 설계(FSD)는 프론트엔드 애플리케이션을 스캐폴딩하기 위한 아키텍처 방법론입니다. 간단히 말해, '코드 구성에 관한 규칙과 규칙의 모음'입니다. 이 방법론의 주된 목적은 끊임없이 변화하는 비즈니스 요구사항에 맞서 프로젝트를 더 이해하기 쉽고 체계적으로 만드는 것입니다.

 

🔎 스캐폴딩(scaffolding) : 애플리케이션의 뼈대를 재빨리 세우는 기법
ex) 코드 생성기, CLI, 템플릿 변환 등

 

 

정리해보자면, FSD는 애플리케이션을 작은 기능 단위로 나누고 각 기능 단위마다 독립적인 사용자 인터페이스, 비즈니스 로직 및 데이터 레이어를 가지도록 설계하는 방법론입니다.

 

FSD의 핵심 아이디어는 애플리케이션을 각각의 사용자가 원하는 기능 또는 사용 사례에 따라 작은 부분으로 나누는 것입니다. 각 기능 단위는 독립적으로 개발, 테스트 및 배포될 수 있으며, 이는 개발자들이 특정 기능에 집중하고 전체 시스템의 복잡성을 줄이는 데 도움이 됩니다.

 

이러한 방식으로 FSD는 애플리케이션을 더욱 모듈화하고 관리 가능한 단위로 분해하여 개발 및 유지보수를 단순화하고, 사용자 경험을 중심으로 기능을 개발할 수 있는 장점을 제공합니다. 또한, 새로운 기능을 추가하거나 기존 기능을 변경할 때 애플리케이션 전체에 영향을 미치지 않고 해당 기능만 업데이트할 수 있는 유연성을 제공합니다.

 

FSD는 모듈들을 어떤 식으로 관리하는지, 구조를 살펴볼까요?

 

 

FSD의 구조

FSD는 Layer, Slice, Segment 총 세 가지 파트로 나뉘어집니다.

Segment가 모여 Slice를 이루고, Slice가 모여 Layer를 이루는 계층적 구조로 구성되어 있습니다.

 

지금부터 각 파트에 대해 살펴볼까요~?

 

 

📁 Layer

레이어는 최상위 폴더이자 애플리케이션 분할의 첫 번째 단계에 속합니다.

각 레이어에는 그 자체의 고유한 책임 영역이 할당되어 있으며, 이를 통해 비즈니스 지향적인 구조를 구성합니다.

현재 정의된 레이어는 아래와 같습니다.

└── src/
    ├── app/
    ├── processes/ (deprecated)
    ├── pages/
    ├── widgets/
    ├── features/
    ├── entities/
    └── shared/
  1. app: 애플리케이션 로직이 초기화되는 곳. Provider, router, 전역 스타일 관리
  2. process: deprecated 페이지 간 복잡한 시나리오를 다루는 레이어 (authentication)
  3. pages: 애플리케이션의 각 페이지를 담당. 사용자가 상호작용하는 화면의 구조를 정의
  4. widgets : 독립형 UI 컴포넌트. 다양한 페이지에서 재사용될 수 있는 독립 모듈 포함
  5. features : 사용자 시나리오와 기능을 중심으로 구성되어 비즈니스 가치를 직접적으로 전달 optional
  6. entities : 비즈니스 주체 (User, Product, Order) optional
  7. shared : 비즈니스 로직과 분리된 재사용 가능한 컴포넌트 및 유틸리티 (UI kit, libs, axios 설정 등)

 

FSD의 레이어는 다음과 같은 위계적 구조(hierarchical structure)를 따릅니다.

 

Layer 원칙 1 : 자신보다 아래 단계의 개체에만 접근할 수 있다.

Layer 원칙 2 : 위계가 낮은 컴포넌트일수록 영향을 받는 곳이 많기 때문에 변경은 위험하다.

 

 

 

이 계층 구조는 한 방향으로만의 흐름을 촉진시키기 때문에 예측 가능하고 유지보수가 용이한 코드를 구현할 수 있습니다.

그런데 FSD를 실제로 적용해보면 widget과 feature, entity의 구분이 모호해지는 경우가 발생하게 됩니다. 🫠

다음의 가이드를 따르면 문제를 보완할 수 있습니다.

 

  • widgetspages 컴포넌트에서 조합하여 사용하기 위한 거의 완성된 독립 기능들
  • featureswidgets를 구성하기 위한 비즈니스 로직의 구체적인 표현 기능들 (결제, 재생, 좋아요, 환불 등)
  • entitiesfeatures에서 구체적인 동작이 부여되기 전인 비즈니스 주체들 (유저, 비디오, 좋아요 버튼 등)
  • shared → 특정 비즈니스 로직에 속하지 않는 재사용 대상들 (AxiosInstance, types, ButtonBase, layout 등)

 

 

📁 Slices

기능 분할 설계에서 레이어가 큰 그림이라면, 슬라이스는 이 그림을 더 세밀하게 구분하는 역할을 합니다.

슬라이스는 애플리케이션 분해의 두 번째 레벨을 나타내며, 각 레이어 내에서 비즈니스 엔티티에 따라 코드를 구조적으로 그룹화합니다.

예시 폴더 구조

 

 

각 레이어 단계에 추가되는 슬라이스의 네이밍은 프로젝트의 비즈니스 영역에 직접적으로 영향을 받기 때문에 프로젝트 별로 다양성을 갖게 됩니다.

 

슬라이스들은 프로젝트의 핵심 비즈니스 로직을 반영하며, 각각의 슬라이스는 프로젝트 내에서 중요한 역할을 수행합니다.

슬라이스는 다음의 규칙을 따릅니다.

 

슬라이스 내의 코드는 직접적으로 공유되지 않아야 한다.

 

 

슬라이스 간에는 격리 규칙이 엄격히 적용되어, 서로 간에 코드를 직접 공유하지 않기 때문에 코드베이스 내에서 각 슬라이스의 독립성을 보장할 수 있습니다.

 

슬라이스를 통해 개발자는 프로젝트의 구조를 더욱 명확하게 이해할 수 있으며, 각 비즈니스 영역의 요구 사항에 따라 코드를 효율적으로 조직할 수 있습니다. 또한, 이런 구조를 통해 새로운 기능의 추가나 기존 기능의 수정 시 관련 코드를 쉽게 찾고, 변경의 영향을 최소화할 수 있습니다.

 

언뜻 보면 슬라이스의 사용은 단순히 코드를 그룹화하는 것 같지만, 이는 프로젝트의 비즈니스 로직을 반영하는 구조적이고 의미 있는 방식

으로 코드를 조직화하는 전략입니다.

 

 

📁 Segment

슬라이스를 통해 프로젝트를 비즈니스 중심의 구성 요소로 나눴다면, 슬라이스 내부에서 더욱 세분화된 구조를 실현하는 것이 바로 세그먼트의 역할입니다.

 

세그먼트는 슬라이스 내 코드를 목적에 따라 분류하고 조직화하여 코드의 가독성과 유지보수성을 높이는데 중요한 역할을 합니다.

일반적으로 사용되는 세그먼트들은 다음과 같습니다.

  • api: 필요한 서버 요청
  • UI: 슬라이스의 UI 컴포넌트
  • model: 비즈니스 로직, 즉 상태와의 상호 작용. actionsselectors가 이에 해당
  • lib: 슬라이스 내에서 사용되는 보조 기능
  • config: 슬라이스에 필요한 구성값이지만 구성 세그먼트는 거의 필요하지 않음
  • consts: 필요한 상수

 

각 슬라이스 내에서 세그먼트는 특정 작업 분야에 초점을 맞춥니다.

이런 세분화는 개발자가 프로젝트의 특정 부분을 신속하게 이해하고 수정할 수 있도록 도와 개발 과정에서의 혼란을 최소화합니다.

 

 

⚙️ Public API

Public API는 index.ts와 같은 진입점 파일을 두어 필요한 기능만 슬라이스나 세그먼트에서 불러올 수 있도록 설정하는 것입니다. 이를 통해 각 슬라이스와 세그먼트의 효율적인 상호작용을 보장합니다.

 

Public API는 다음의 원칙을 따릅니다.

Public API 원칙 1 : 앱의 Slice와 Segment들은 Public API index 파일에 정의된 기능과 컴포넌트만 사용한다.
Public API 원칙 2 : Public API에 정의되지 않은 내부적인 부분은 격리된 것으로 간주하여 그 자신의 Slice나 Segment만 여기에 접근할 수 있다.

 

공개 API를 통한 상호작용은 코드베이스의 유지보수를 용이하게 하고, 프로젝트의 확장성에 긍정적인 영향을 미칩니다. 또한, 애플리케이션의 모듈성을 강화하는 중요한 역할을 합니다.

 

 

🔎 아키텍처에 대해 더 자세히 알아보기

💭 추상화와 비즈니스 로직

기능 분할 설계에서는 레이어의 계층에 따라 추상화 수준과 비즈니스 로직의 복잡성이 달라집니다.

계층이 높은 레이어, 즉 사용자에게 더 가까운 레이어는 특정 비즈니스 요구 사항에 더 많이 종속되며, 복잡한 비즈니스 로직을 포함하는 경향이 있습니다.

반면, 계층이 낮은 레이어, 즉 시스템의 핵심부에 가까운 레이어는 추상화 수준이 더 높습니다. 이 레이어들은 일반적으로 재사용성이 높고, 레이어 자체의 자율성이 적으며 전체 시스템의 기반 기능을 제공합니다.

예를 들어, 데이터 모델링, 네트워크 통신, 데이터 캐싱과 같은 기능은 낮은 계층에서 처리됩니다.

 

 

✨ FSD로 해결 가능한 문제들

 

기능 분할 설계는 결합도를 낮추고 응집력을 높이는 것을 목표로 합니다. FSD는 객체 지향 프로그래밍의 핵심 개념인 다형성, 캡슐화, 상속, 추상화를 통해 이러한 목표를 달성합니다.

  • FSD에서 추상화와 다형성은 레이어를 통해 달성됩니다. 각 레이어는 특정 추상화 수준을 가지며, 이는 낮은 레이어가 더 추상적이 되도록 하여 더 높은 레이어에서 재사용될 수 있게 합니다. 이런 구조는 레이어가 특정 매개변수나 속성에 따라 다양하게 작동할 수 있도록 함으로써 다형성의 원칙을 적용합니다.
  • 캡슐화는 슬라이스와 세그먼트의 공개 API를 통해 달성됩니다. 이는 슬라이스 또는 세그먼트 내부의 세부 사항을 격리시키며, 필요한 기능과 컴포넌트만을 외부에 노출시킵니다. 공개 API의 사용은 슬라이스 또는 세그먼트의 내부 구현을 변경해도 외부 사용에 영향을 미치지 않도록 보장하며, 이는 코드의 격리 및 재사용성을 촉진합니다.
  • 상속은 레이어를 통해 달성됩니다. 이는 더 높은 레이어가 낮은 레이어의 기능을 재사용할 수 있게 하며, 이 구조는 코드의 중복을 줄이고, 애플리케이션의 일관성을 유지하는 데 도움이 됩니다.