Skip to content
Open
Show file tree
Hide file tree
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
102 changes: 28 additions & 74 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,83 +1,37 @@
# [6주차] 기본과제

여러분은 게시판을 관리할 수 있는 Admin 코드를 인수인계 받았습니다. 다행히 못 알아볼 정도의 더티코드는 아니고 적당히 잘 만든 것 같지만 정리가 된 것 같지 않은 아주 현실감 있는 익숙한 느낌의 코드였습니다.
## 과제 셀프회고

우리는 지금까지 배웠던 내용을 토대로 해당 코드들을 클린하게 정돈하고 FSD 아키텍쳐를 활용해서 정리해보려고 합니다.
너무 궁금했던 부분인데 이사와 겹쳐서 과제를 거의 못했다 ,, 🥲 그래도 FSD의 개념에 대해 이해할 수 있었고 살짝이지만 적용해볼 수 있어서 좋았다. 꼭 다시 해야지..!

**여러분들은 해당 코드를 분석해보니 다음과 같은 문제점들을 발견할 수 있었습니다.**
### FSD 탄생 배경

1. 컴포넌트가 너무 크고 복잡하다.
2. Typescript를 사용하고 있지만 Type처리가 부실하다.
3. 상태관리의 개념없이 너무 많은 상태를 가지고 있다.
4. useEffect 관리가 안되고 있다.
5. 비동기 처리 로직이 복잡하게 구성되어 있다.
* 프로젝트가 커질수록 디렉토리 구조가 무너진다
* 기존 방식은 규모가 커질수록 관심사의 경계가 무너지고 디렉토리 탐색이 어려워짐
* 컴포넌트, 유틸, API 등이 기능이나 도메인이 아닌 역할 중심으로 분리되어 있어 이해가 어렵고 재사용도 힘듦
* 사실 역할 중심으로 분리하는게 익숙해서 도메인 중심으로 다시 설계하려니 너무 헷갈렸다. (ui만 나눴지만..)
* 관심사 분리가 제대로 되지 않음
* 예를 들어 로그인 기능의 UI, API 호출, 상태 관리, 검증 로직이 여러 디렉토리에 흩어짐
* 어떤 코드가 어디에 위치해야 하는지 명확한 기준이 없어 일관성도 떨어짐
* 시간이 지날수록 점점 심해짐
* 코드의 예측 가능성과 유지보수성이 떨어짐
* 새 팀원이 프로젝트에 참여했을 때, 코드의 위치를 파악하기 힘듦

**여러분들은 해당 코드를 개선하기 위해서 다음과 같은 목표를 세웠습니다.**
### FSD의 해결 방법

1. Typescript를 확실히 사용해서 코드의 이해와 리팩토링에 대한 안정성을 확보합니다.
2. 컴포넌트에 단일 책임 원칙을 부여하여 작게 만들고자 합니다.
3. 적절한 관심사의 분리를 통해서 폴더구조를 만드려고 합니다.
4. 이때 배웠던 FSD를 한번 적용해보려고 합니다.
* Layer + Slice + Segment 구조 제안
* 수직: app > processes > pages > widgets > features > entities > shared 레이어 구조로 계층을 나누고
* 수평: ui / model / api / lib / config 세그먼트로 관심사를 분리
* Slice: 특정 도메인(예: product, cart, auth 등)에 대한 폴더 구조 단위
* 규칙 기반으로 파일을 배치하도록 강제
* 기능별로 관련된 모든 코드를 한 곳에 모음 (ex. entities/product/)
* 팀 내 일관된 컨벤션을 유지하고 협업의 효율성을 높임 (진입장벽이 좀 존재할듯)

**Basic 과제**
### FSD를 적용하며 어려웠던 점

상태관리를 사용하여 관심리를 분리하고 FSD 폴더 구조를 적용하기
* 기능과 관심사의 명확한 분리
* 페이지네이션은 피처인가?, 검색 필터 UI는 위젯인가? 같은 고민을 계속 했다.
* 컴포넌트나 로직이 어떤 슬라이스에 속하는지 판단하는게 어려웠다.
* 특히 UI + 상태 관리 (zustand store)의 위치 선정에서 애매함 느낀 것 같다.
* 상태(store)의 역할과 위치 정하기
* post 관련 zustand store는 어디에 둬야할지 등.. 엔티티와 피쳐 사이에 고민이 되었다.

```markdown
목표:
전역상태관리를 이용한 적절한 분리와 계층에 대한 이해를 통한 FSD 폴더 구조 적용하기

- 전역상태관리를 사용해서 상태를 분리하고 관리하는 방법에 대한 이해
- Context API, Jotai, Zustand 등 상태관리 라이브러리 사용하기

- FSD(Feature-Sliced Design)에 대한 이해

- FSD를 통한 관심사의 분리에 대한 이해
- 단일책임과 역할이란 무엇인가?
- 관심사를 하나만 가지고 있는가?
- 어디에 무엇을 넣어야 하는가?


체크포인트
- [ ] 전역상태관리를 사용해서 상태를 분리하고 관리했나요?
- [ ] Props Drilling을 최소화했나요?
- [ ] shared 공통 컴포넌트를 분리했나요?
- [ ] shared 공통 로직을 분리했나요?
- [ ] entities를 중심으로 type을 정의하고 model을 분리했나요?
- [ ] entities를 중심으로 ui를 분리했나요?
- [ ] entities를 중심으로 api를 분리했나요?
- [ ] feature를 중심으로 사용자행동(이벤트 처리)를 분리했나요?
- [ ] feature를 중심으로 ui를 분리했나요?
- [ ] feature를 중심으로 api를 분리했나요?
- [ ] widget을 중심으로 데이터를 재사용가능한 형태로 분리했나요?
```



# [6주차] 심화과제

여러분들은 비동기 코드가 들어가고 서버와 통신을 하기 시작하니 상태관리가 엄청나게 복잡해진다는 것을 알았습니다. 그래서 서버상태관리를 도입을 하면 보다 함수형 패러다임으로 선언적으로 비동기를 관리할 수 있다는 사실을 알게 되었습니다.

**여러분들은 해당 코드를 개선하기 위해서 다음과 같은 목표를 세웠습니다.**

1. TanstackQuery를 이해하고 적용해보자.
2. api의 관리를 잘 할 수 있는 표준을 만들자.

**Advanced 과제**

TanstackQuery를 이용하여 코드를 개선하기

```markdown
목표:
서버상태관리 도구인 TanstackQuery를 이용하여 비동기코드를 선언적인 함수형 프로그래밍으로 작성하기

- TanstackQuery의 사용법에 대한 이해
- TanstackQuery를 이용한 비동기 코드 작성에 대한 이해
- 비동기 코드를 선언적인 함수형 프로그래밍으로 작성하는 방법에 대한 이해

체크포인트
- [ ] 모든 API 호출이 TanStack Query의 useQuery와 useMutation으로 대체되었는가?
- [ ] 쿼리 키가 적절히 설정되었는가?
- [ ] fetch와 useState가 아닌 선언적인 함수형 프로그래밍이 적절히 적용되었는가?
- [ ] 캐싱과 리프레시 전략이 올바르게 구현되었는가?
```
10 changes: 8 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,16 @@
"lint": "eslint .",
"preview": "vite preview",
"test": "vitest",
"coverage": "vitest run --coverage"
"coverage": "vitest run --coverage",
"predeploy": "npm run build",
"deploy": "gh-pages -d dist"
},
"dependencies": {
"@tanstack/react-query": "^5.75.5",
"react": "^19.1.0",
"react-dom": "^19.1.0"
"react-dom": "^19.1.0",
"vite-tsconfig-paths": "^5.1.4",
"zustand": "^5.0.3"
},
"devDependencies": {
"@eslint/js": "^9.25.1",
Expand All @@ -30,6 +35,7 @@
"eslint": "^9.25.1",
"eslint-plugin-react-hooks": "^5.2.0",
"eslint-plugin-react-refresh": "^0.4.20",
"gh-pages": "^6.3.0",
"globals": "^16.0.0",
"jsdom": "^26.1.0",
"lucide-react": "^0.503.0",
Expand Down
Loading