Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[22주차 1] Feature Sliced Design #221

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
150 changes: 150 additions & 0 deletions new/feature-sliced-design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
# Feature-Sliced-Design (FSD)


> 기능 분할 설계(Feature-Sliced Design, FSD)는 애플리케이션의 복잡성을 관리하고 코드의 유지 보수성을 높이기 위한 설계 방식입니다. FSD는 기능을 기준으로 코드를 모듈화하고, 각 모듈이 독립적으로 개발 및 테스트될 수 있도록 합니다.

FSD는 3개의 계층으로 이루어집니다.

- **레이어(Layers)**
- **슬라이스(Slices)**
- **세그먼트(Segments)**

## Layers

app, pages, widgets, features, entities, shared로 구성

```jsx
// FSD Layers 폴더 구조
src/
├── app/
├── ~~processes~~(사용 X)/
├── entities/
├── features/
├── pages/
├── widgets/
└── shared/
```


> **하위 레이어는 상위 레이어를 참조(import)할 수 없습니다.**
>
> 예시:
>
> - entities 레이어에서 widgets 레이어 참조 불가
> - app 레이어는 모든 하위 레이어 참조 가능


1. `App`
- 앱의 진입점과 전역 설정을 포함한 폴더

- 라우팅, 전역 스타일, 프로바이더 등 포함
- everything that makes the app run — routing, entrypoints, global styles, providers.
2. `Pages`
- 전체 페이지 또는 중첩 라우팅의 큰 부분을 담당하는 컴포넌트를 포함하는 폴더

- 화면 구성 요소를 포함하며, 특정 경로에서 사용자에게 보여지는 UI 담당
- 한 페이지는 여러 기능을 포함할 수 있음
- full pages or large parts of a page in nested routing.
3. `Widgets`
- 큰 단위의 기능이나 UI를 포함하는 폴더
- 하위의 레이어(entities, features)를 이용하여 특정 피쳐에서 사용할 수 있는 UI 포함

- 해당 도메인에 widget layer가 불필요하다면 생략 가능
- 특정 의존성과 강결합 되어있기 때문에 여러 페이지에서 재사용하지 못할 수 있음
- 엔티티에 속하지 않고 features에 속하지 않으면서 이 둘을 합쳐서 활용하는 곳
- 리액트에선 컴포넌트와 훅이 대표적
- large self-contained chunks of functionality or UI, usually delivering an entire use case.
4. `Features`
- 유저의 인터렉션과 관련된 로직, 특정 비즈니스 로직이 담겨있는 레이어
- 재사용 가능한 기능 단위
- 각 기능은 독립적으로 작동하며 특정 도메인 로직 수행
- 애플리케이션의 주요 기능 모듈화
- 데이터를 UI의 상태 (리액트의 state 등)으로 변환하거나 그러한 값들을 비즈니스 값으로 변환하는 곳
- 주로 이벤트 리스터, 훅, 상태관리도구, 리액트 쿼리 등이 위치

- 동사형으로 폴더명 생성 (ex. GetSellerList, SendComment…)
- *reused* implementations of entire product features, i.e. actions that bring business value to the user.
5. `Entities`
- 도메인 모델과 관련된 핵심 개념 포함
- 간단하게 말하면, 비즈니스 로직의 주체
- 특정 프레임워크나 방법론에 속하지 아닌 범용적인 비즈니스 로직

- 해당 도메인과 연관된 api 호출 함수 정의
- 프로젝트에서 다루는 비즈니스 엔티티를 나타내는 폴더
- ex. User, Product, Order 등
- business entities that the project works with, like `user` or `product`.
6. `Shared`
- 프로젝트 전반에 걸쳐 재사용 가능한 기능을 포함하는 폴더

- 특정 비즈니스 로직에 의존하지 않는 일반적인 유틸리티나 컴포넌트 포함
- reusable functionality, especially when it's detached from the specifics of the project/business, though not necessarily.

## Slices

비즈니스 도메인을 폴더로 나눈 것 (ex. User, Seller, PreSeller…)

각 슬라이스 폴더의 도메인은 index 파일로 export 한다.

```tsx
└── features/ #
├── Seller/ # Internal structure of the feature
| ├── ui/ #
| ├── model/ #
| ├── {...}/ #
├── **index.ts** # Entrypoint features with its public API
```

## **Segments**

세그먼트의 이름은 ui, model, lib, api 등이 될 수 있다.

- api: api를 호출하기 위한 코드
- ui: UI 컴포넌트
- model: 비즈니스 로직, data aggregation 함수
- lib: infra structure code

```bash
├── features/
+ | ├── add-to-cart/ {ui, model, lib}
+ | ├── choose-delivery/ {ui, model, lib}
├── entities/{...}
+ | ├── delivery/ {ui, model, lib}
+ | ├── cart/ {ui, model, lib}
+ | ├── product/ {ui, model, lib}
├── shared/
+ | ├── api/
+ | ├── lib/ # helpers
+ | ├── config/ # constants
```

### 기존 리액트 폴더 구조에서 마이그레이션 예시

![Untitled](Feature-Sliced-Design%20(FSD)%20c2bbec66564e423394352f64335f6e0e/Untitled%203.png)

### react-query와 적용하기

참고 링크: https://feature-sliced.design/docs/guides/tech/with-react-query

```bash
src/ #
├── app/ #
| ... #
├── pages/ #
| ... #
├── entities/ #
| ├── {entity}/ #
| ... └── api/ # Query-factory
| ├── `{entity}.query` # where are the keys & functions
| ├── `get-{entity}` # Entity getter function
| ├── `create-{entity}` # Entity creation function
| ├── `update-{entity}` # Entity update function
| ├── `delete-{entity}` # Entity delete function
| ... #
| #
├── features/ #
| ... #
├── widgets/ #
| ... #
└── shared/ #
... #
```