
팀 프로젝트와 개인 프로젝트를 진행하면서, 지금까지 익숙하게 사용해 온 모놀리식 아키텍처 외에도 다양한 설계 방식을 배워 보고 싶다는 생각이 들었다. 앞으로 새롭게 진행할 프로젝트 또는 현재 작업 중인 프로젝트의 폴더구조 역시 참고해 개선할 수 있도록 기능 분할 설계 - 최고의 프런트엔드 아키텍처 아티클을 읽고 핵심만 요약 정리해 추후 해당 아키텍처에 대해 빠르게 참고하거나 적용할 때 도움이 될 수 있도록 이 글을 작성하게 되었다.
(이 글은 노션에서 처음 작성되었으며, 노션의 원문 스타일이 네이버 블로그에 완전히 적용되지 않아, 일부 가독성이 떨어질 수 있는 점 양해 부탁드립니다.)
기능 분할 설계 아키텍처(Feature-Sliced Design, FSD)?
먼저 기능 분할 설계 아키텍처란 무엇일까? 기능 분할 설계는 대규모 프론트엔드 애플리케이션을 기능 단위로 나누어 구조화하는 현대적인 아키텍처 방법론으로 각 기능을 독립적으로 개발, 테스트, 유지보수할 수 있도록 하는 걸 목표로 하는 아키텍처이다.
기능 분할 설계는 크게 레이어, 슬라이스, 세그먼트 총 세 가지로 나눌 수 있다.

레이어
레이어는 기능 분할 설계에서 가장 상위 개념으로, 애플리케이션을 책임 단위로 구분한 계층 구조를 의미한다.
총 7개의 레이어로 구성되며, 상위에서 하위로 흐르는 단방향 의존성을 갖는다. 즉, 상위 레이어는 하위 레이어를 사용할 수 있지만, 하위 레이어는 상위 레이어에 의존할 수 없다. 또한 하위로 내려갈수록 재사용성은 높아지지만, 변경에 민감해질 수 있다는 특징이 있다.
레이어명 | 설명 | |
---|---|---|
상위 | app | 애플리케이션 로직이 초기화되는 진입점 |
processes | 여러 페이지에 걸쳐 있는 프로세스 처리 (선택적) | |
pages | 애플리케이션 페이지 | |
widgets | 페이지의 UI 컴포넌트 | |
features | 사용자 시나리오, 기능 (선택적) | |
entities | 비즈니스 엔티티 (선택적) | |
하위 | shared | 종속되지 않는 재사용 가능한 컴포넌트, 유틸리티 |
슬라이스
각 레이어는 슬라이스라는 하위 디렉토리 단위로 구성된다. 슬라이스는 특정 비즈니스 도메인 또는 기능 단위로 코드를 그룹화한 구조이며, 단순한 추상 개념이 아니라 실제 서비스에서 명확히 구분 가능한 기능 단위를 의미한다.
슬라이스의 이름은 비즈니스 목적에 따라 유연하게 정해지며, 정해진 표준은 없지만 팀 내에서 일관성 있게 유지해야 한다.
레이어 | 슬라이스 (예시) | |
---|---|---|
상위 | app | providers, styles, index |
processes | ||
pages | home, profile, about | |
widgets | newsfeed, catalog, header, footer | |
features | user, auth, favorites, filter-uesrs | |
entities | user, session | |
하위 | shared |
세그먼트
슬라이스는 세그먼트라는 하위 단위로 구성된다. 세그먼트는 슬라이스 내부의 코드를 역할별로 나누는 구조이며, 팀의 합의에 따라 구성 방식이나 디렉토리 이름을 자유롭게 설정할 수 있다.
세그먼트(예시) | 설명 |
---|---|
api | 서버 요청 |
UI | 슬라이스의 UI 컴포넌트 |
model | 비즈니스 로직, 즉 상태와의 상호 작용 |
lib | 슬라이스의 보조 기능 |
config | 슬라이스의 필요 구성값 (거의 필요 X) |
consts | 필요한 상수 |
공개 API
각 슬라이스 및 세그먼트에는 공개 API(index.ts/js
)가 존재하며,
이를 통해 외부에 필요한 기능만 명시적으로 노출하고, 나머지 내부 구현은 격리할 수 있다.
세부 규칙은 아래와 같다.
-
외부에서는 오직 해당 슬라이스의 index 파일을 통해서만 기능에 접근해야 한다.
-
index 파일에 정의되지 않은 내부 파일은 슬라이스, 세그먼트 내부에서만 사용 가능하며,
외부에서 직접 참조해서는 안 된다.
기존 아키텍처와의 비교
기능 분할 설계 아키텍처는 기존 아키텍처들과 어떤 점에서 다를까?
vs 고전적인 아키텍처
전통적인 프론트엔드 아키텍처는 컴포넌트 간 암묵적인 연결과 모듈 간 복잡한 의존성으로 인해 프로젝트가 커질수록 유지보수와 확장이 어렵다는 단점이 존재한다. 반면, 기능 분할 설계는 명확한 개념과 표준화된 구조를 기반으로 하여, 이러한 문제들을 체계적으로 해결할 수 있다.
vs 모듈식 아키텍처
단순한 모듈식 아키텍처와 비교했을 때는 어떨까?
모듈 단위로 파일을 나누는 방식은 구조가 단순해 MVP가 필요한 경우, 수명이 짧은 프로젝트에 장점이 있지만, 아래와 같은 단점을 갖고 있다.
- 기능을 어떤 모듈, 컴포넌트에 넣을지 명확하지 않을 수 있음
- 다른 모듈 내에서 모듈 사용이 어려움
- 비즈니스 엔티티 저장 문제
- 복잡한 구조 (글로벌 함수의 암시적 종속성에 의함)
따라서 장기적으로 운영되거나, 팀 단위로 협업하는 프로젝트의 경우 기능 분할 설계가 더 적합한 선택이 될 수 있다.
MVP란?
Minimum Viable Product의 약자로, 시장에 빠르게 출시할 수 있을 정도로 핵심 기능만 갖춘 최소한의 제품을 뜻한다.
Next.js에서의 주의사항
기능 분할 설계는 대부분의 프론트엔드 프레임워크와 잘 어울리지만, Next.js에서는 몇 가지 구조적 제약과 충돌이 발생할 수 있다. 특히 아래 두 가지 사항이 문제될 수 있어, 해결 방법을 함께 명시한다.
- Next.js의 파일 기반 라우팅 시스템
- 기능 분할 설계의 app 레이어의 부재
경로 분리 방식
Next.js의 pages
디렉토리는 루트에 그대로 두고, 나머지 구조는 src
폴더 내부에 구성한다.
디렉토리 분리 방식
라우팅의 목적에 따라 아래 두 가지 디렉토리로 구분한다.
pages-flat
→ 평면적인 페이지 구조pages
→ 중첩 라우트 또는 더 복잡한 페이지 구조
추가적으로, Next.js에서는 app이라는 폴더 개념이 기본적으로 존재하지 않기 때문에, 기능 분할 설계의 app 레이어를 적용하려면 레이아웃 패턴을 활용해야 한다.
아키텍처의 장단점 정리
마지막으로, 기능 분할 설계 아키텍처의 장점과 단점을 정리하며 글을 마무리하고자 한다.
장점
- 아키텍처 구성 요소(레이어, 슬라이스, 세그먼트)를 쉽게 교체, 추가, 제거할 수 있다.
- 구조가 표준화되어 있어 협업과 유지보수에 유리하다.
- 프로젝트가 커져도 확장성이 뛰어나며 일관성을 유지할 수 있다.
- 특정 프레임워크나 라이브러리에 종속되지 않고, 개발 스택에 독립적인 방식이다.
- 구조가 비즈니스 로직 중심으로 설계되기 때문에, 도메인 지식과 코드가 잘 연결된다.
- 모듈 간 연결이 명시적이며 제어 가능해, 예기치 않은 부작용을 방지할 수 있다.
단점
- 다른 아키텍처에 비해 초기 진입장벽이 높다.
- 팀 전체가 구조에 대한 이해와 규칙 준수가 필요하다.
- 도전 과제와 문제를 즉시 해결해야 한다. (장점으로 볼 수도 있다.)