Tech Dive

소상공인 혁신 플랫폼 '사장이지' 프론트엔드 개발 #2: FSD

들어가며


안녕하세요. KT AX플랫폼본부에서 프론트엔드 개발을 담당하고 있는 유현우입니다. 


이번 주제는 (사장이지 Nx Monorepo와 MicroFrontend 도입기 ) 아티클과 이어지는 내용입니다. FSD 아키텍처를 검토하고 프로젝트에 적용하기까지의 과정을 담았습니다. 




아키텍처 선택 과정


FSD 아키텍처와 Atomic 패턴이 후보군이었습니다. 각각의 구조가 가진 특징과 팀 상황에서의 적합성을 기준으로 비교하며, 사장이지 프로젝트에 더 적합한 아키텍처가 무엇인지 고민했습니다.

장단점 비교

01.jpg


각각의 장.단점이 명확했기에, 아래 두 가지를 충족할 수 있는 아키텍처를 선택했습니다. 


1. 어떻게 해야 다수의 개발자가 일관된 구조로 코드를 생산할 수 있을까

다수의 개발 인력이 투입된 프로젝트인 만큼, 아키텍처 표준이 없을 경우 코드가 중구난방으로 작성될 위험이 있었습니다. 대표적인 리스크로는 코드 복잡성 증가와 중복 코드 생성이 있으며, 개발 인력이 많아질수록 이러한 문제는 걷잡을 수 없이 확산될 가능성이 컸습니다.


2. 폴더 구조만 봐도 프로젝트 구조를 파악할 수는 없을까

요구사항을 기준으로 프로젝트가 대규모로 확장될 것이 확실시되었기 때문에, 도메인별로 코드의 역할과 용도를 폴더 구조만 보고도 파악할 수 있어야 했습니다. 그리고 QA 기간에는 개발자가 관련 코드를 빠르게 찾을 수 있는 구조가 필요했습니다.

코드의 일관성과 구조적 명확성을 동시에 확보할 수 있고, Slices를 통해 코드 탐색 비용을 효과적으로 줄일 수 있는 FSD 아키텍처를 최종적으로 선택했습니다. 다음은 FSD(Feature-Sliced-Design) 아키텍처에 대한 설명입니다. 



FSD 아키텍처란 무엇인가

02.jpg

이미지 출처 : FSD 공식문서


FSD 아키텍처는 Feature-Sliced Design의 약자로, 프론트엔드 애플리케이션을 효율적이고 확장 가능하게 설계하기 위한 구조화 방법론입니다. 기본 개념은 기능(feature)을 중심으로 코드를 분리하여 도메인 간 의존성을 줄이고 각 레이어가 자신의 역할에만 집중하도록 하여, 기능 단위로 독립적인 개발.확장이 가능하게 합니다. 

아래는 Layers, Slices, Segments에 대한 상세 설명입니다. 

Layers

FSD 구조는 크게 6가지로 구성됩니다. 

Title
Description
app
  애플리케이션 초기화 및 전역 설정 (라우팅, 테마 등)
pages
  라우트 단위의 화면 구성 (여러 Widgets / Features를 조합한 최상위 UI)
widgets
  특정 기능 단위의 UI 및 로직 (예: User 리스트)
features
  재사용 가능한 독립적인 기능 단위 (예: 검색, 필터)
entities
  도메인 모델과 비즈니스 로직 관리 (User, Product, Order 도메인)
shared
여러 곳에서 공유되는 코드 (UI 컴포넌트, 유틸리티 등)



Slices

첨부된 그림을 예시로 들면 user, post, comment 도메인별로 구분되어 있는 것이 Slices 개념입니다. 비즈니스 도메인별로 코드를 분할합니다. 같은 레이어 안에서 다른 Slices를 참조할 수 없으며, 이는 높은 응집도와 낮은 결합도를 유지하는데 도움이 됩니다.

Segments

목적에 따라 코드를 그룹화합니다. 관례적으로 ui, api, model, lib, config 폴더가 포함됩니다. 

Title
Description
ui
  UI와 관련된 모든 것: UI 컴포넌트, 날짜 포맷터, 스타일 등
api
  백엔드 상호작용: request 함수, 데이터 타입, mapper 등
model
  데이터 모델: 스키마, 인터페이스, 스토어, 비즈니스 로직
lib
  슬라이스 안에 있는 다른 모듈이 필요로 하는 라이브러리 코드
config
  설정 파일과 기능 플래그




실무에서 마주한 문제와 해결책


문제 ➊ : FSD 러닝커브 존재 

모두가 FSD 개념을 정확히 이해하면 베스트였겠지만 끊임 없이 주어지는 요구사항으로 물리적인 학습 시간이 부족했습니다. 대부분의 프로젝트 일정이 그러하듯, 개별적인 학습 시간을 가질만한 여유가 없었습니다. 요구사항이 실시간으로 바뀌는 것도 이슈 중에 하나였는데, 특정 기능들은 어느 레이어에 배치해야 할지 결정하는 커뮤니케이션 비용이 발생했습니다.

➊ 해결책 : pages, entities, shared 중심으로 레이어 간소화

  1.  pages: 화면에 보이는 UI 적인 부분들의 집합
  2. entities: 도메인 관련된 api, type, util 등의 비즈니스 로직을 entities/{segments}에 배치
  3. shared: entities, pages 에서 재사용되는 공통 코드 영역

f1o-d5a5dcd90fe242d0824d5f6121d22828-052.png



문제 ➋ : 요구사항이 급변함에 따라 Layer가 지속적으로 변경됨

요구사항이 수정되면서 기존 화면이 사라지거나 부분적으로 변경됨에 따라 pages에서 widgets으로 이동해야 하는 상황이 빈번하게 발생했습니다. 공통화를 하더라도 이미 여러곳에서 사용하고 있었기 때문에 기존 동작을 보장하는데 리스크가 있었습니다. 

➋ 해결책 : 점진적 구조 개선을 위한 코드 공통화 시간 확보

1) 기능 개발과 별개로 리팩토링을 위한 일정을 별도로 확보
2) 하위 레이어부터 상위 레이어 순서로 코드 이동
3) 재사용성이 애매한 경우에는 개별 pages에 배치 

* As-is) account, user 도메인이 pages 내부에 산재됨
* To-be) 도메인별로 entities, pages에 코드 분산

문제2.png



문제 ➌ : 코드 조각이 나뉘어져 데이터 흐름 파악이 어려움

FSD 구조 특성상 기능 단위로 코드가 분리되다 보니, 하나의 기능을 이해하기 위해 여러 레이어를 오가야 하는 경우가 많았습니다. 특히 API 호출 위치가 분산되어 있어 데이터가 어디서 생성되고 어떻게 전달되는지 파악하는데 어려움이 있었습니다.

➌ 해결책 : GET API 호출 가능한 레이어 제한 (pages, widgets, features)

1) 데이터 흐름을 단순화하기 위해 GET API 호출 위치를 pages, widgets, features레이어로 제한
2) 데이터 흐름을 직관적으로 파악하기 위해 index.tsx 파일에서만 GET API를 호출함
3) POST API는 UI 렌더링과 직접적인 연관성이 없기 때문에 호출 구간에는 제한을 두지 않음 

이미지



사장이지 FSD 최종 형상

pages는 페이지 단위의 코드와 GET API를 호출하고, UI·상태·로직으로 구성됩니다. widgets와 features는 재사용 가능한 레이어로, pages와 동일하게 API 호출이 가능하나 (pages -> widgets -> features) 계층 순서로 데이터가 호출 됩니다. 레이어 시각화를 위해 pages, widgets, features에 별도의 색상을 입혔습니다. 

화면 1. 창업 상권분석 (pages, widgets)

03.jpg

  • pages: 창업 상권분석 화면의 최상위 레이어로, 총 3개의 widgets을 import 하고 있습니다.  
  • widgets: 상단 필터와 탭 전환에 따라 전환되는 주요 콘텐츠로 구성됩니다. 


화면 2. 하이오더 매장통계 (pages, widgets, features)

04.jpg

  • pages: 하이오더 매장통계 화면의 최상위 레이어로, 총 2개의 widgets을 import 하고 있습니다.  
  • widgets: 탭 전환에 따라 전환되는 주요 콘텐츠로 구성되고, (시간 별, 결제 수단 별, 상품 별) 탭을 포함해서 총 6개의 features를 import 하고 있습니다. 
  • features: 매장 통계 페이지에서 GET API를 호출하는 최소 단위 레이어입니다. 


폴더 구조

화면 2. 하이오더 매장통계(store-statistics) 기준으로 구성했습니다. 

05.jpg


사장이지에 적용된 폴더 구조와 실제 화면에서의 FSD를 알아보았습니다. 

이를 통해 레이어 간 역할 분리와 데이터 흐름이 실제 화면에서 어떻게 반영되는지 확인할 수 있었습니다. 



AI 생성툴과 FSD 활용법

이번 장에서는 AI 생성툴과 FSD 아키텍처의 시너지를 알아보겠습니다. Cursor, Figma MCP를 활용하여 FSD 도입 전후를 비교했습니다. 두 케이스 모두 결과는 같았지만, 폴더 구조에는 차이가 있었습니다. 

FSD 도입 전

06.jpg


Figma MCP를 활용하여 코드가 생성되었습니다. 브라우저에서 UI를 확인했을 때 별 문제가 없었지만, 개발자가 생성된 코드를 한 눈에 파악하기란 쉽지 않았습니다. 대표적으로 2가지 단점이 확인됐습니다. 

08.jpg


물론 개발자 자체적으로 AI 코드를 하나씩 확인하는 것도 방법이지만, 시간이 많이 소요되는 작업이었고 이후에도 일관된 구조를 유지하기 어렵다는 한계가 있었습니다. 다음은 단점을 커버한 FSD 도입 후의 AI 코드 생성 결과입니다. 


FSD 도입 후

07.jpg


브라우저에서 확인한 결과는 FSD 도입 전의 왼쪽 이미지와 동일했습니다. 미리 정의된 팀 내 README(FSD 가이드)를 AI 생성툴이 참조하도록 설정했습니다.  FSD 구조를 접합했을 때 다음과 같은 장점이 있었습니다. 

09.jpg


결론적으로, FSD 활용으로 AI 생성툴의 코드 생성에 일관성이 더해졌습니다. 




마무리


FSD 아키텍처 도입은 단순한 구조 변경이 아닌, 팀의 개발 방식과 코드 스타일을 하나로 정렬하는 과정이었습니다. 초기에는 러닝커브에 대한 부담이 있었지만, 팀 상황에 맞게 유연하게 적용했습니다. 그 과정에서 다음과 같은 긍정적인 효과를 확인할 수 있었습니다.

10.jpg


물론 아키텍처를 한 번에 완성하기는 쉽지 않았습니다. 실제로는 팀 상황과 요구사항에 맞게 계속해서 조정하고 개선해 나가는 과정이 필요했습니다. 결국 좋은 아키텍처란 한 번에 정의되는 것이 아니라, 팀과 함께 점진적으로 발전해 나가는 구조라고 생각합니다.


FSD 아키텍처 도입기는 여기서 끝이 아닙니다. 아키텍처를 정의하고 적용하는 것만큼, 이를 실제 개발 환경에서 일관되게 유지해 나가는 과정 역시 중요한 과제였습니다. 다음 후속 글에서는 FSD 아키텍처를 지속하기 위한 방법론으로서 하네스 엔지니어링 도입기와, 그 과정에서 얻은 실질적인 인사이트를 다뤄볼 예정입니다.

다음 후속 아티클을 기약하며 이번 글은 여기서 마무리하겠습니다. 


🔥 공동 기여자들: P-Web개발부서 (백지경, 김남일, 박지원, 김수현) 

유현우

KT P-Web 개발부서에서 근무하고 있습니다. 지속 가능한 코드에 대해 항상 고민하고 있습니다.

이전 글