-
Notifications
You must be signed in to change notification settings - Fork 1
[Init] FSD 구조의 폴더 구조 세팅 & 절대 경로 세팅 #9
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
Conversation
- shared/styles 폴더를 추가합니다. tokens 폴더도 추가하여 스타일 세팅 시에 사용되는 토큰을 저장하도록 합니다. - 절대 경로를 지정합니다. (개발용/빌드용)
🚀 빌드 결과✅ 린트 검사 완료 |
- 경로 string 형태 수정
- 에러 픽스 후 다시 원상복구 할 commit 입니다.
|
꺅 😽 Comfit 서비스의 상황에 맞게 FSD 구조를 적절히 경량화하여 초기 폴더 구조 세팅이 잘 된 것 같아요!! 수고하셨습니다🖤 지금 시점에서 다만 FSD 구조를 100% 따르지 않는 부분, 특히 케로로 이미지도 잘 보이는거 했고 🫡 PR 템플릿 중 ‘✏️ Summary’가 주석이 아니라 인용 형태로 되어 있는건 이번 PR에서 함께 수정해주시면 좋을 것 같습니다!! 진짜 수고 많으셨습니다 최고최고ㅠ!! 🥹👍 |
| resolve: { | ||
| alias: { | ||
| "@": path.resolve(__dirname, "./src"), | ||
| "@app": path.resolve(__dirname, "./src/app"), | ||
| "@pages": path.resolve(__dirname, "./src/pages"), | ||
| "@widgets": path.resolve(__dirname, "./src/widgets"), | ||
| "@shared": path.resolve(__dirname, "./src/shared"), | ||
| "@images": path.resolve(__dirname, "./src/shared/assets/images"), | ||
| "@icons": path.resolve(__dirname, "./src/shared/assets/icons"), | ||
| "@api": path.resolve(__dirname, "./src/shared/api"), | ||
| "@config": path.resolve(__dirname, "./src/shared/config"), | ||
| "@model": path.resolve(__dirname, "./src/shared/model"), | ||
| "@styles": path.resolve(__dirname, "./src/shared/styles"), | ||
| "@types": path.resolve(__dirname, "./src/shared/types"), | ||
| "@ui": path.resolve(__dirname, "./src/shared/ui"), | ||
| }, | ||
| }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tsconfig에는 @lib/*가 있는데 vite.config.ts alias에는 @lib가 빠져있어서 빌드 시에 @lib/... import가 깨질 수도 있을 것 같은데, alias 세팅에 @lib관련 세팅(@lib: path.resolve(__dirname, "./src/shared/lib"))도 추가하는게 어떨까요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
오 실수로 빼먹은 거 같아여!! 예리한 지적 감사합니다~
| "paths": { | ||
| "@/*": ["src/*"], | ||
| "@app/*": ["src/app/*"], | ||
| "@pages/*": ["src/pages/*"], | ||
| "@widgets/*": ["src/widgets/*"], | ||
| "@shared/*": ["src/shared/*"], | ||
| "@images/*": ["src/shared/assets/images/*"], | ||
| "@icons/*": ["src/shared/assets/icons/*"], | ||
| "@api/*": ["src/shared/api/*"], | ||
| "@config/*": ["src/shared/config/*"], | ||
| "@lib/*": ["src/shared/lib/*"], | ||
| "@model/*": ["src/shared/model/*"], | ||
| "@styles/*": ["src/shared/styles/*"], | ||
| "@types/*": ["src/shared/types/*"], | ||
| "@ui/*": ["src/shared/ui/*"] | ||
| } | ||
| }, | ||
| "include": ["src"] | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
레이어 단위(@app/@pages/@widgets/@shared)랑 shared segment 단위(@api/@config/...)까지 꼼꼼하게 paths 열어두신 점 굳굳입니당!! 👍
src/app/main.tsx
Outdated
| import { StrictMode } from "react"; | ||
| import { createRoot } from "react-dom/client"; | ||
| import App from "./App.tsx"; | ||
| import App from "./App"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
여기에서도 alias 적용해서 @app/App처럼 경로 가져와도 좋을 것 같아요 😊
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
바아로 반영했습니둥~
odukong
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
아티클과 PR내용 모두 채영님께서 많은 고민을 했다는게 느껴지는 글들이라 하나하나 소중히 너무 잘 읽었습니다... !
그래서 그런지 어떤 흐름으로 프로젝트를 구조화하고, 어떤 파일은 어떤 레이어로 위치하게 만들어야하는지 이전보다 좀 더 명확해진 것 같습니다!!
기존 FSD처럼 처음부터 너무 세분화해 구조화하기보다 지금처럼 경량화 된 FSD로 구조화하여 점진적으로 구체화시켜나가는 방향성도 너무 좋구요 🥰
현재 FSD 구조 기준으로 몇 가지 제 의견 덧붙여보자면,
채영님이 말씀해주신대로 컴핏 내부에서는 공통 컴포넌트는 아니지만 여러 페이지에서 사용되는 컴포넌트들이 많습니다. 그래서 widgets 계층이라는 레이어를 만들고, widgets 계층에서 의미 있는 블록 단위로 나누는 것이 적합하다고 말씀해주신 것! 저도 동의하는 바예요.
하지만 문득 widgets 계층만으로는, 프로젝트에서 사용되는 컴포넌트(공통 컴포넌트 제외)를 모두 widgets 계층에 정의하기에는 무리일 수도 있겠다는 생각이 들었어요.
그렇다고 해당 pages에서만 사용되는, 특히나 복잡한, 행동이 있는 컴포넌트를 pages 계층에서 정의하기에는 이미 구현되어있는 컴포넌트를 조립하는 기능을 중점으로 두는 pages 계층의 책임의 의미가 조금 달라지지 않을까 합니다.
그래서 features라는 레이어 계층을 추가로 두어, widgets는 의미있는 UI블록에 집중한다면, features는 비지니스로직을 포함하는 세부적인 컴포넌트(무언가 행위가 일어나는가)를 features에 위치하게 하는 방식도 한 번 제안드려요.
app → processes → pages → widgets → features → entities → shared
물론 FSD구조가 단방향 의존성을 추구하기 때문에, widgets는 features레이어를 참고할 수 있고, pages는 features와 widgets을 모두 참조할 수 있는 방향인거죠!
간단하게 예시를 들자면, widgets에는 북마크 된 회사정보 레이아웃에 대한 company-card 컴포넌트가 위치하고 북마크를 취소하는 버튼을 bookmark-delete를 features레이어에 위치시켜 company-card가 행동을 하는 bookmark-delete버튼을 포함하게 되는 흐름이 될겁니다.
추가적으로 pages계층은 라우팅을 위한 페이지가 바로 위치하는 것이 통상적으로 사용되는 경우가 많은 것 같아 ui slice도 별도로 정의하지 않고 아래처럼 pages 폴더 아래 바로 위치하게 하는 방식도 좋을 것 같다는 의견이에요.
├─ 📁 onboarding
├─ 📋 onboarding-page.tsx
└─ 📋 onboarding-page.css.ts
지금 말씀드린 것들은 순전히 개인 의견이기 때문에 회의 때 다시 한번 의견 나눠보고 기준을 픽스하면 좋을 것 같아요!!
노션에 남겨주신 마이페이지에 대한 개인적인 의견 남겨보자면, pages 레이어는 라우팅단위입니다. 마이페이지 (/mypage)나 북마크 페이지(/mypage/bookmark)역시 라우팅이 나누어지기 때문에 pages 아래 my-page와 book-mark처럼 별도의 slice로 구분하는 것이 적절하다는 의견입니다. 이와 비슷한 경우의 FSD구조를 나타내는 프로젝트 구조 예시인데 한번 참고해 주세요!!
이 부분도 마찬가지로 회의 때 의견 나눠보면 좋을 것 같아요!!
그리고 이미 코드리뷰는 유진님이 잘 남겨주셔서 제가 남겨드릴 부분은 딱히 없는 것 같네요 허허 수고 많으셨어요!! (≧∀≦)ゞ
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PR이랑 작성해주신 FSD 관련 아티클 잘 읽었습니다 !!!
왜 FSD 구조를 도입했는지, 기준을 어디까지 가져갈지에 대한 고민 과정이 잘 정리돼 있어서 이번 구조 세팅의 방향성을 이해하기가 정말 수월했던 것 같아요 !
프로젝트 규모를 고려해서 app, shared, pages, widgets까지만 점진적으로 도입한 판단도 너무 좋았고,
회의 때 한 번 더 의견 나눠보고, 수빈님이 말씀해주신 것처럼 features 레이어를 도입하는 방향도 충분히 좋은 선택지일 것 같아요
그리고 PR 템플릿 인용으로 되어 있는 부분도 이번 PR에서 주석으로 한 번만 정리해주시면 감사하겠습니다 !ㅎㅎ 폴더 구조에 절대 경로까지 작업하시느라 정말 수고 많으셨습니다 ❤️🔥
유진님, 수빈님 꼼꼼한 코드리뷰도 읽어보면서 많이 배워갑니다 ... 👍
- pr 템플릿 주석 수정 - 빠진 절대 경로 추가 - app import 경로 수정
|
오늘 논의한 내용을 토대로 폴더 구조 변경 완료했습니다! 변경된 내용은 아래와 같아요. 1.
변경 내용이 잘 반영되었는지 확인 한 번씩 부탁드려요! 추가적인 의견 역시 환영 🤗🤗 |
|
제가 확인할 때는 아까 회의에서 이야기했던 방향대로 폴더 구조가 잘 잡힌 것 같습니다!! 다른 리뷰 반영된 부분들도 잘 확인했습니다. 구조 정리랑 리뷰 사항 빠르게 반영하느라 수고 많으셨습니다ㅠ!! 👍🖤 |
|
변경된 폴더구조에 대한 반영사항들 잘 확인했습니다❕ |
|
변경 내용 반영된 폴더 구조 잘 확인했습니다 ! |
✏️ Summary
FSD 구조의 폴더 구조를 세팅했어요. 또한 그에 맞게 적절한 절대 경로를 세팅했습니다.
📑 Tasks
1. fsd 구조의 폴더 구조 세팅
📌 comfit은 왜 FSD 구조를 도입했나요?
fsd 구조를 도입하지 않는, 기존 방식은 아래와 같아요.
하지만 이런 방식은 몇 가지 문제점을 가지고 있었어요.
FSD 구조를 사용하면 표준화된 구조로 이해 관계 파악이 용이하고, 기능을 중점으로 디렉토리가 나뉘어 코드의 위치가 명확해지기 때문에 위와 같은 문제를 해결할 수 있다고 판단했고, comfit 웹파트는 FSD 구조를 도입하기로 결정했어요. 또한 FSD 구조는 공식 문서를 통해 가이드라인을 제공하기 때문에 이해 및 적용 면에서 훨씬 수월하다는 장점이 있어요 👍
📌 최종 폴더 구조
프로젝트의 규모를 고려했을 때 layer의 여섯 계층을 모두 넣는 것은 과도한 세분화일 수 있어요. 실제로 공식 문서에서는 처음부터 모든 레이어를 나누어 개발하기보다는 점진적 도입을 제안하고 있어요.
서비스의 규모, 주어진 시간 등 다양한 요소를 고려하였을 때
app과shared,pages에widgets까지 추가하여 4가지의 layer만 사용하는 것으로 결정했어요. features와 entities까지 사용하게 되면 과하게 복잡해지고 그렇게 되면 fsd 구조를 도입한 것이 오히려 협업에 방해가 될 수도 있다고 생각하고 내린 결론이에요.app계층: 프로젝트 초기화, 라우팅 설정 등/routes→ 라우팅/styles→ global, reset, theme 등 글로벌 스타일/providers→ 프로바이더, React Context Provider/layout→ 공통적으로 감싸지는 레이아웃pages계층: 도메인 기준 폴더 분리(라우팅 기준)widgets계층: 의미 있는 ui 블록 단위shared계층: 모든 레이어에서 import 가능api/→ api 인프라 레벨로 axiosInstance, base response 타입 등 지정assets/→ 이미지, 아이콘, 폰트 등config/→ 라우트 상수, 공통 상수 등 변경 빈도가 낮은 상수값(기존constants와 같은 역할)lib/→ 유틸 함수(기존utils와 같은 역할)model/→ useDebonce, useKeyboard같은 UI와 직접 연결되지 않는 훅(기존hooks와 같은 역할)styles/→ 스타일 토큰 및 theme 정의types/→ 여러 곳에서 사용되는 typesui/→ 공통 컴포넌트(주의: Button, Input, Modal과 같은 정말 basic한 공컴만 이곳에 둘 것)2. 절대 경로 세팅
구조에 맞게 절대 경로를 세팅했습니다. 이 때 shared 내부에 있는 segment들 또한 절대 경로로 지정하여 사용할 수 있도록 하여 편의성을 높였습니다.
👀 To Reviewer
🔔 ETC
PR 템플릿에서 '✏️ Summary' 부분 설명이 주석이 아니라 인용으로 되어있네요! 너무 작은 수정이라 해당 pr에서 같이 수정해도 될지 여쭤봅니다~!!