
먼저 Layers, Slices, Segment 폴더로 구분하고 Depth를 3으로 제한한다.
폴더와 파일이 많아지고 Depth가 많아지면 파일 import 할 때 ../../../ ……. 과 위치를 구분하기 힘들어진다.
Layers
app
전역설정. Provider, Router, Client같은 HOC가 slice 기준. 어플리케이션 전반적으로 적용되는 기능. 프로바이더, 라우터, 전역스타일, 전역 타입 선언 등
- providers
- styles
- types
pages
주소 단위의 페이지. 각각의 주소별 페이지가 slice 기준
widgets
UI 컴포넌트. entities와 feature를 의미있는 블럭으로 만든 레이어.. 어떻게 묶을지는 재사용 여부에 따라 정하면 됨.
- header
- footer
feature
동사적 의미로, 동작 구현 파일. 동사가 slice 기준. api segment에서는 feature의 행동을 요청한다.
entities
데이터 파일. 데이터가 slice 기준. api segment에서는 entities 데이터를 조회
shared
재사용가능한 컴포넌트와 유틸리티 포함. UI키트, axios 설정, 어플리케이션 설정. slice 없음.
- utill
- hook
- typeings
그외..
process
현재 안 씀. 페이지들이 여러 개 연달아 되어 있는 것으로 예를 들어 회원가입 페이지에서 스탭 바이 스탭 플로우로 넘어가는 페이지들에 해당하는데, 해당 페이지들은 widget 폴더로 넘기면 된다.
예시
<Shared.Button
onClick={forkFreature.api.fork}
icon={shared.icon.fork}
data={forkEntity.model.forkCount}
/>
// pages/profile/ui/ProfilePage.tsx
/** 프로필 페이지 */
export const ProfilePage = () => {
// .. 각종 state들..
return (
<>
<ProfileHeader ... />
<ProfileBody ... />
<ProfileFooter ... />
</>
)
}
// widgets/ProfileBody/ui/ProfileBodySection.tsx
/** 프로필 작성 영역 */
export const ProfileBodySection = (...) => {
// ...
}
// features/saveProfileData/ui/SaveProfileDataButton.tsx
/** 프로필 저장 버튼 */
export const SaveProfileDataButton = (...) => {
// ...
}
깃허브에서 FSD 사용 예시
- 버튼을 페이지 말고도 전체적으로 사용할 것 같다? → shared
- 버튼의 동작 → feature
- fork 버튼을 구현할 때, fork에 대한 행위는 feature에 있을 것이고, 그 밑에 children으로 fork에 대한 entities 컴포넌트가 있고, 공유되는 UI를 담당하는 버튼 컴포넌트가 있는 것이다.
- feature - entities(데이터) / shared(UI)
☝ Layers의 제약조건
- feature 안에 entities, shared를 포함시킬 수 있음
- app 폴더에는 나머지 Layers를 포함시킬 수 있음
- 그 외에는 구조 변경 불가.
- shared는 slices가 없음. 공유되는 것이라서 어떤 도메인에 종속되지 않음.
- index.js와 index.ts를 적극 사용해야 함. index.js에서 export 한 것만 import 가능하게끔. FSD를 사용한다면 index 파일을 사용해야 한다!(약속) 이렇게 해야 어떤 컴포넌트는 private/public 컴포넌트를 캡슐화할 수 있음
- 캡슐화 : 서로 연관 있는 속성과 기능들을 하나의 캡슐(capsule)로 만들어 데이터를 외부로부터 보호하는 것
- // DO NOT ❌ import { SubmitLikeButton } from 'features/submitLike/ui/SubmitLikeButton.tsx // GOOD ✅ import { SubmitLikeButton } from 'features/submitLike
Layers 구조
📂app
┣ 📂feature
┃ ┣ 📂entities
┃ ┗ 📂shared
┣ 📂pages
┣ 📂widgets
┣ 📜index.tsx
┗ 📜providers.tsx
Segment
- api - 필요한 서버 요청.
- UI - 슬라이스의 UI 컴포넌트.
- model - 비즈니스 로직, 즉 상태와의 상호 작용. actions 및 selectors가 이에 해당
- lib - 슬라이스 내에서 사용되는 보조 기능.
- config - 슬라이스에 필요한 구성값이지만 구성 세그먼트는 거의 필요하지 않음.
- consts - 필요한 상수.
Next.js 에서 FSD 폴더 구조 사용하기
┣ 🗂️ app # NextJS app folder
┣ 🗂️ src
┃ ┣ 🗂️ app # FSD app folder
┃ ┣ 🗂️ entities
┃ ┣ 🗂️ features
┃ ┣ 🗂️ pages
┃ ┣ 🗂️ shared
┃ ┗ 🗂️ widgets
FSD 공식문서에는 위와 같이 앱라우터를 위한 별도 폴더와 FSD를 위한 app 폴더를 나누어서 관리하라고 제시한다.
이 외에도 많은 방법이 있는데,
아래 링크에 프로젝트에서 참고해 보기!
https://feature-sliced.design/examples
[출처]
https://feature-sliced.design/docs/guides/tech/with-nextjs
https://emewjin.github.io/feature-sliced-design/#nextjs와-fsd의-충돌
'개발' 카테고리의 다른 글
| RESTfull API란 무엇인가? (2) | 2024.11.05 |
|---|