FSD 아키텍쳐 : 프론트엔드 아키텍쳐

김태성·2024년 9월 13일
0
post-custom-banner

FSD 아키텍쳐

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

Features

  • Explicit business logic : 명시적인 비즈니스 로직. 도메인 범위 덕분에 쉽게 검색 가능한 아키텍처이다.
  • Adaptability : 적응성. 새로운 요구 사항에 따라 아키텍처 구성 요소를 유연하게 교체 및 추가할 수 있다.
  • Tech debt & Refactoring : 기술 부채 및 리팩토링. 각 모듈은 사이드 이펙트없이 독립적으로 수정/재작성할 수 있다.
  • Explicit code reuse : 명시적 코드 재사용. DRY와 로컬 사용자화 사이의 균형이 유지된다.

Scheme

FSD에서 프로젝트는 레이어로 구성되며, 각 레이어는 슬라이스로, 각 슬라이스는 세그먼트로 구성된다.

Layers

레이어는 디렉토리의 최상위이고, 애플리케이션 분해의 첫번쩨 단계이다. 레이어의 수는 최대 7개로 제한되어 있으며, 일부는 옵셔널하지만 표준화되어 있다. 현재는 아래와 같이 레이어가 구분되어 있다. 각 레이어는 고유의 책임영역이 있고, business-oriented하다.

  • App
    애플리케이션 로직이 초기화되는 공간이다. Providers, routers, global styles, global type declarations, 등등 이 여기서 정의된다. 즉 애플리케이션의 진입점 역할을 한다.

  • Processes(deprecated, optional)
    이 레이어는 여러 페이지에 걸쳐있는 프로세스를 처리한다.(ex, multi-step registration) 이 레이어는 더이상 사용되지 않는다.

  • Pages
    entities, features, widgets 레이어 로 전체 페이지를 구성하기 위한 구성 레이어이다. 이 레이어는 애플리케이션의 페이지가 포함된다.

  • Widgets
    entities와 features 레이어를 의미있는 블록으로 결합하는 composition layer이다. 페이지에서 사용되는 독립적인 UI 컴포넌트들이 있다. (ex, IssuesList, UserProfile)

  • Features(optional)
    이 레이어는 business value를 전달하는 유저 시나리오와 같은 기능을 다룬다. (ex, SendComment, AddToCart, UsersSearch)

  • Entities(optional)
    이 레이어는 business entities를 나타낸다.(ex, User, Product, Order)

  • Shared
    이 레이어에는 특정 비즈니스 로직에 종속되지 않은 재사용가능한 컴포넌트와 유틸리티가 포함되어 있다. (ex, UIKit, libs, API)

이러한 레이어들은 코드베이스를 구성하고, 모듈식, 유지보수 가능, 확장 가능한 아키텍쳐를 만드는데 도움이 된다.

FSD의 주요 특징중 하나는 계층적 구조이다. 이 구조에서 entities 레이어는 features 레이어가 더 상위이기 때문에 features 레이어의 기능을 사용할 수 없다. 비슷하게, features 레이어는 widget 이나 processes 레이어의 기능을 사용할 수 없다. 즉, 위 레이어는 아래 레이어만 활용할 수 있는데 이는 한방향으로만 향하는 선형적인 흐름을 유지하기 위한것이다.

따라서 계층구조에서 레이어의 위치가 낮을 수록 코드의 많은 곳에서 사용될 가능성이 높기 때문에 변경하는 것이 위험하다. 예를들어, shared 레이어의 UI-kit는 features, widgets, pages 레이어에서 사용될 수 있다.

Slices

각 레이어 에는 애플리케이션 분해의 두번째 레벨인 slice라는 하위 디렉토리가 있다. slice에서 연결은 추상적인 것이 아니라, 특정 business entities에 대한 것이다. 즉, 비즈니스 도메인 별로 코드를 분할해서 논리적으로 관련된 모듈을 서로 가깝게 유지하여 코드 베이스를 쉽게 탐색할 수 있다. 슬라이스는 같은 레이어에서 다른 슬라이스를 사용할수 없으므로 응집력이 높고 결합력이 낮다.

slice는 프로젝트의 business 영역에 의해 직접 결정되기때문에 이름이 표준화되어있지 않다. 예를들어, photo gallery를 생각해보면, photo, album, gallery와 같은 섹션이 있을 수 있다. 그리고 SNS는 post, user, newsfeed와 같은 슬라이스가 필요할 것이다.

밀접하게 관련된 부분들은 구조적으로 디렉토리내에서 그룹화되어있지만, 다른 슬라이스와 같은 격리 규칙을 준수해야하며, 이 디렉토리에 있는 코드는 직접적으로 공유되면 안된다.

Segments

각 슬라이스는 세그먼트로 구성된다. 세그먼트는 기술적 목적에 따라 슬라이스 내의 코드를 나누는데 도움이 되는 작은 모듈이다. 팀의 합의에 따라 세그먼트는 구성과 이름이 결정된다. 가장 일반적인 세그먼트는 ui, model(store, actions), api, lib(utils/hooks) 이다.

  • Api : 서버 요청
  • UI : 슬라이스의 UI 컴포넌트
  • Model : 비즈니스 로직, 즉 state와의 상호작용. 예를들어 action, selector가 해당된다.
  • Lib : 슬라이스 내에서 사용되는 보조 기능

FSD 예시(SNS 애플리케이션-글카드)

  • App : routing, store, global styles 설정이 있다.
  • Pages : 앱의 각 페이지에 대한 라우팅 구성요소가 포함되어 있으며, 대부분 구성이며, 로직은 거의 없다.
  • Widgets : 백엔드의 관련 호출에 연결되어 있는 content와 interactive 버튼이 조립되어 있는 post card가 있다.
  • Features : 카드의 상호작용(좋아요 버튼)와 이러한 상호작용을 처리하는 로직을 포함한다.
  • Entities : 콘텐츠와 인터렉티브 요소를 위한 slot이 있는 card의 shell을 포함한다. 글 작성자를 나타내는 tile도 여기에 있지만 다른 슬라이스의 entities에 있다.

Public API

각 슬라이스와 세그먼트는 public API를 가진다. public API는 index파일이며, 이 파일을 통해 필요한 기능만 외부로 내부내고 불필요한 기능들은 격리할 수 있다. Index 파일이 진입점 역할을 한다.

Public API는 import와 export로 단순하게 작동하므로 애플리케이션을 변경할때 코드의 모든곳에서 import를 변경할 필요가 없다.

규칙
1. Access Control
Public API는 모듈의 콘텐츠에 대한 접근을 제어해야 한다. 애플리케이션의 다른 부분은 public API에 표시된 모듈 엔티티만 접근할 수 있다. 표시되지 않은 모듈 내부부분은 모듈 자체만 접근할 수 있다.

  1. Sustainability for changes
    public API는 모듈 내부의 변경사항에 대해 지속가능해야 한다. 즉 내부 구조의 변경이 public API의 변경으로 이어지면 안된다.

  2. Integrability
    publicAPI는 쉽고 유연한 통합이 가능해야 한다. 나머지 애플리케이션에서 사용하기 편리해야 한다.

단점

  • 대부분의 인기있는 번들러에서, re-exports때문에 code-splitting이 잘 작동하지 못하는데, 이것은 이 접근방식으로 tree-shaking을 하면 모듈의 일부가 아닌 전체 모듈만 버리는 것이 안전하기때문이다. 예를들어, authModel을 page model로 import 하면, AuthForm 컴포넌트 페이지에서 아용되지 않더라도, 페이지 청크안에 들어간다.
  • 결과적으로, 브라우저는 “for the company” 번들에 포함된 모든 모듈을 포함하여 그안에 있는 모든 모듈을 처리해야하므로 청크의 초기화 비용이 많이 든다.

해결방법
webpack을 사용하면 re-exports 파일이 부작용이 없는것으로 표시할 수 있으므로 이러한 파일로 작업할때 webpack이 공격적인 최적화를 사용할 수 있다.

Deeper into architecture

Abstraction and business logic
계층이 높은 레이어일수록 특정 business node에 더 종속이 되고, 더많은 business logic이 포함된다. 계층이 낮은 레이어일수록 추상화 수준이 높고, 재사용성이 높고, 레이어 자체의 자율성이 적다.

profile
@flip_404
post-custom-banner

0개의 댓글