Skip to content

Commit

Permalink
Create fsd.md (#214)
Browse files Browse the repository at this point in the history
  • Loading branch information
newminkyung authored Jun 29, 2024
1 parent 1c3ff2b commit 1f6f234
Showing 1 changed file with 115 additions and 0 deletions.
115 changes: 115 additions & 0 deletions new/fsd.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
## Feature Sliced Design

> 컴포넌트의 잘못된 설계로 인해 여러 어려움을 겪게 되는 경우가 많다.
>
> 예를 들어, 커스텀 훅을 추가할 때 어디에 추가해야하는지 결정하기 어렵거나 특정 컴포넌트를 수정할 때 import된 파일들이 얽혀 영향도를 파악하기 어려운 경우가 있다.
>
> 이러한 문제를 해결하기 위해 페이지 단위로 컴포넌트를 구성하거나, 관련 로직들을 모아두는 구성을 주로 사용하곤 한다.
>
> 하지만 애플리케이션이 복잡해질수록 폴더구조도 깊어지고 결국 복잡해지는 문제가 발생한다.
>
> 이러한 문제를 회사에서 겪고 있고, 이를 개선하고자 FSD를 검토하고 있다.
---

- FSD는 애플리케이션을 기능 단위로 분리해서 각 기능을 독립적으로 분리하는 방법입니다.
- 컴포넌트, 훅, api 등을 기능 단위로 묶어 관리함으로써, 애플리케이션의 복잡성을 낮출 수 있습니다.

---

- FSD는 레이어, 슬라이스, 세그먼트를 기준으로 개념이 나뉜자.

![image](https://github.com/10000-Bagger/free-topic-study/assets/80238096/82eaa751-e17d-4e23-9c94-d2ad5e1478db)


### 레이어
![image](https://github.com/10000-Bagger/free-topic-study/assets/80238096/bddfa097-0bcd-4e55-9f2d-2123df32c89e)

- 최상위 디렉토리
- 각 레이어마다 고유한 책임 영역이 있음
- `app`: 모든 애플리케이션의 진입점 역할
- 프로바이더, 라우터, 전역 스타일, 전역 타입 선언 등이 정의되는 곳
- `pages`: 애플리케이션의 페이지
- `widgets`: 페이지에 사용되는 독립적인 UI 컴포넌트
- `features`: 비즈니스 사용자 시나리오와 기능
- ex. 좋아요, 리뷰 작성, 제품 평가
- `entities`: 비즈니스 엔티티
- ex. 사용자, 리뷰, 댓글
- `shared`: 재사용 가능한 컴포넌트와 유틸리티
- UI 키트, axios 설정, 애플리케이션 설정, 헬퍼 함수 등

---

위 레이어들은 한 방향으로만 향하는 선형적인 흐름을 갖고 있음
- entities 레이어는 features 레이어의 기능을 사용할 수 없음
- features 레이어는 widgets 레이어나 processes 레이어의 컴포넌트를 사용할 수 없음

- 계층 구조에서 레이어의 위치가 낮을수록 코드의 더 많은 곳에서 사용될 가능성이 높기 때문에, 레이어를 변경하는 것이 더 위험

### 슬라이스
- 레이어의 하위 디렉토리
- 슬라이스의 주요 목표는 코드를 값별로 그룹화
- 슬라이스 이름은 프로젝트의 비즈니스 영역에 따라 직접 결정

![image](https://github.com/10000-Bagger/free-topic-study/assets/80238096/5061fc2b-32d0-4a71-bf2a-ed9b2dfca45a)

- 구조적으로 디렉토리 내에 그룹지을 수 있지만 다른 슬라이스와 동일한 격리 규칙을 준수해야함

### 세그먼트
- 각 슬라이스는 세그먼트로 구성
- 일반적으로 사용되는 세그먼트는 다음과 같다

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

---

## 인덱스 파일을 통해 관심사 분리
- index파일을 통해 슬라이스 또는 세그먼트에서 필요한 기능만 외부로 추출하고 불필요한 기능은 격리
- 인덱스 파일에 정의된 슬라이스의 기능과 컴포넌트만 사용
- 인덱스 파일에 정의되지 않은 슬라이스 또는 세그먼트의 내부 부분은 격리된 것으로 간주되며 슬라이스 또는 세그먼트 내부에서만 접근

---

## FSD가 문제를 해결하는 방식
- 결합을 느슨하게 하고 응집력을 높이는 것
- 레이어: 추상화와 다형성
- 낮은 레이어는 더 추상화 되어있기 때문에 더 높은 레이어에서 재사용
- 특정한 매개변수나 속성에 따라 컴포넌트나 기능이 다르게 작동
- 인덱스 파일: 캡슐화
- 슬라이스와 세그먼트 외부에서 필요하지 않은 것을 격리
- 슬라이스의 내부 세그먼트에 대한 접근은 제한
- 인덱스 파일이 슬라이스 또는 세그먼트의 기능 및 컴포넌트에 접근할 수 있는 유일한 방법

### 고전적인 아키텍처와의 비교
![image](https://github.com/10000-Bagger/free-topic-study/assets/80238096/5613c9dd-1484-4dde-b4bd-169b9d140e2f)

- 기존 아키텍처의 문제점은 컴포넌트 간의 암묵적인 연결과 모듈의 복잡성 때문에 프로젝트가 유지보수하기 어려워진다는 것
- 기능을 어떤 모듈이나 컴포넌트에 넣을지 명확하지 않을 때가 있음
- 다른 모듈 내에서 모듈 사용에 어려움이 있음
- 비즈니스 엔티티를 저장하는 데 문제
- 글로벌 함수의 암시적 종속성으로 인해 구조가 복잡
- MVP가 필요하거나 수명이 짧은 프로젝트를 개발하는 경우에는 단순한 모듈식 아키텍처가 FSD보다 적합할 수 있음

## Next.js와 FSD의 충돌
- Next.js는 FSD와 잘 작동하지만, 페이지의 파일 라우팅과 앱의 부재라는 두 가지 영역에서 충돌이 발생

### pages
- Next.js에서는 pages 디렉토리가 파일 라우팅을 담당하며, 각 컴포넌트가 하나의 라우트
- FSD에서는 pages는 페이지들의 평면 목록을 담고 있는 레이어로 사용

#### 해결방법
1. Next.js와 FSD를 함께 사용할 때, [root]/pages/와 같이 Next.js 페이지를 애플리케이션 루트에 저장하는 방법
2. 두 개의 디렉토리를 유지
- FSD의 페이지들의 평면 목록을 다시 이름 지은 pages-flat과 Next.js의 중첩된 라우트를 위한 pages
- 실제 페이지 코드는 pages-flat에 저장되고, 그 후에 pages로 내보낼 수 있음

#### app
- app 레이어의 모든 기본적인 기능은 Next.js에서 처리
- 페이지와 독립적으로 전체 애플리케이션에 대해 무언가를 실행해야 하는 경우 레이아웃 패턴을 사용하여 전체 애플리케이션을 위한 레이아웃을 만들 수 있음

0 comments on commit 1f6f234

Please sign in to comment.