지금까지 개발을 하면서, 다른 사람들의 프로젝트를 보면 “와, 대박... 이 사람 진짜 잘한다!” 싶은 순간이 종종 있었다.
왜 그런지 생각해보니, 그 사람들에겐 자기만의 틀이 있었다.
반면 나는 새로운 프로젝트를 할 때마다 구조도, 네이밍도, 폴더 구성도 매번 달랐다.
심지어 같은 프로젝트를 할때도 일관성이 없다는 걸 알게 되었다.
그렇기에 나에게는 없는 자신만의 틀이 더 빛나보였던 것 같다.
그래서 이번 글은 이전 스터디에서 진행했던, 폴더 구조를 바탕으로 ⭐️나만의 틀⭐️을 조금씩 만들어 보려한다.
회사를 다니던 도중, 조직개편이 이루어지면서 컨벤션이 명확한 프로젝트에 투입이 되기 시작했다.
자연스럽게 회사에서 정한 컨벤션으로 개발을 하게 되었고, 기존 코드들도 컨벤션에 맞게 리팩토링을 하는 작업도 했다.
처음에는 익숙하지 않았지만 빠르게 익숙해 졌다. 그런데 프로젝트의 규모가 클수록 폴더 구조의 아쉬움이 보였다.
회사 컨벤션은 역할 단위로 폴더를 분리하고,
그 내부에서 페이지 단위로 폴더를 만드는 방식이다.
# common - 전체 공통
# page - 각 페이지
src
├── components
│ ├── common
│ └── [page]
│
├── services
│ ├── common
│ └── [page]
│
├── store
│ ├── common
│ └── [page]
│
├── hooks
│ ├── common
│ └── [page]
│
├── pages
│ └── [page]
│
├── utils
│ ├── common
│ └── [page]
│
└── constants
├── common
└── [page]
프로젝트가 작았을 때는 페이지가 많지 않다보니 각 역할 안에 폴더 숫자가 많지 않아 크게 불편하지는 않았다.
그런데 프로젝트가 커지고 페이지가 많아지면서 상황이 달라졌다.
유지/보수를 하거나 기능을 추가될 떄마다 좌측 워크 스페이스 트리가 복잡해져갔다.
예를 들어, Login 페이지에서 컴포넌트와 API, 상태 관리 모두 수정해야 한다면 components/login, services/login, store/login 서로 다른 역할 안에 있는 흩어진 파일들을 찾아가 수정해야 했다.
새로운 페이지를 만들때도 각 역할별 폴더 안에 해당 페이지 폴더를 생성해야하는 불편함이 있었다.
"왜 이렇게 불편하지?"라는 생각을 해봤는데, 원인은 바로 낮은 응집도 였다. 대부분의 파일들은 해당 페이지에서만 사용되는 경우가 많았는데, 역할별로 분리되어 있다보니, 관련된 코드들이 한 곳에 모여있지 않았다.
나는 현재 Next.js를 사용하기 때문에 자연스럽게 페이지 기반으로 개발을 하게 되었다.
그래서 나는 페이지 단위로 폴더를 나누는 것을 기반으로 재사용성을 위해 가장 큰 틀로 세가지를 나누었다.
src
├── shared
│ ├── components
│ ├── services
│ ├── store
│ ├── hooks
│ ├── utils
│ └── constants
└── pages
│ └── [page]
│ ├── components
│ ├── services
│ ├── store
│ ├── hooks
│ ├── utils
│ ├── constants
│ └── page.tsx
└── features
└── [feature]
├── components
├── services
├── store
├── hooks
├── utils
├── constants
└── README.md
이 구조로 프로젝트를 구성하니 확실히 응집도가 높아졌다.
또한 유지/보수할때도 분산되지 않아 훨씬 효율적이었다.
전역에서 재사용되는 코드는 shared에, 여러 페이지에서 사용되는 기능은 features에 정리하면서 재사용성을 챙길 수 있었다.
단점도 존재했다.
프로젝트 규모가 작을 경우에는 과도한 폴더 분리로 독이 될 수 있고, 재사용성을 위한 분리 기준이 명확하지 않다면 오히려 혼란스럽다는 것이었다.
그래서 기본 규칙 두가지를 정했다.
이번 기회에 폴더 구조를 정리하면서 그동안 내가 얼마나 주먹구구식으로 개발해왔는지를 돌아보게 되었다.
아직 이 구조를 실무에 바로 도입하진 못했지만, 나에게 맞는 틀을 정리하는 것은 생각보다 깊은 고민도 필요 했고, 그만큼 뿌듯한 일이었다.
물론 지금 정리한 이 구조로 내 틀이 완성되었다고 생각하지 않는다.
그저 나의 개발을 위한 최소한의 틀을 만들었다 생각한다.
이 글을 읽는 여러분도, 자신만의 틀을 정리하는 시간을 가져보면 좋은 경험을 하지 않을까 생각한다!
태영님의 고민이 묻어나는 글이어서 좋네요
더불어 next.js 가 제공 하는 프로젝트 구조도 한번 같이 살펴보면 좋을 듯 합니다.
여기도 개발자가 어떻게 구조를 설계해야한다라는 철학이 있어요
https://youtu.be/S5Rl3EtBaA0?si=SA0Nfi2yXm0Z9HCN
https://nextjs.org/docs/app/getting-started/project-structure
자신만의 기준을 세운다는게 진짜 중요한 것 같아요! 완벽한 폴더구조는 없고, 현재 상황에 가장 잘 맞는 폴더 구조로 가는게 중요하다고 생각하는데 태영님은 잘 하고 계신다는 생각이 들어요👍🏻
폴더 구조를 보며 궁금한 점은 shared와 features의 차이인데요! 여러 페이지에서 사용하는 features와 전역인 shared에는 어떤 차이가 있는지 궁금합니다. 여러 페이지 vs 전역을 구분하는 기준점이 있을까요?
와 너무 공감돼요. 저도 프로젝트마다 폴더 구조가 들쑥날쑥이라 항상 유지보수할 때 애먹었는데, ‘응집도’라는 말이 진짜 딱이네요. 다음 프로젝트는 이 구조 참고해서 저만의 틀도 만들어봐야겠어요. 감사합니다 🙌
혹시 features 쪽에 있는 상태관리(store)는 보통 어떤 기준으로 위치를 정하시는지 궁금합니다.
현재 저희 팀의 폴더 구조와도 유사하네요.
역할에 맞게 나눠져있다면 찾기는 쉽지만 과도할 경우 유지보수 시에 타고타고타고타고,,,찾아야하는 뎁스가 늘어나서 힘들더라구요.
이렇게 정리하고 자신만의 것을 찾아가시려고 시도한 태영님 멋집니다! ㅎㅎ
크~ 그때 작성 하신다던 나만의 코딩 컨벤션 작성을 하고 계시군요! 작성하면서 정말 많은것들을 고민하게 되고 내 생각을 정리하게 되어서 정말 좋은거 같습니다! 너무 잘 읽었습니다.
저희팀도 최근에 기존 레거시 폴더구조가 불편하다는 점을 인지하고 태영님이 작성해주신 폴더구조 형태와 유사하게 개선하고 있는데 놀랍네요!!
fsd를 할때도 그렇고 항상 고민했던 부분이 feature 폴더였는데, 태영님은 feature를 어떤 기준으로 나누시는지 궁금합니다. 예를들어 글 작성이라는 기능이 있다면 글 작성이라는것을 feature로 나누시는지, 아니면 글이라는 도메인으로 나누시는지요!
여러 사람들과 협업하다보면 충분히 고민할만한 주제였던 것 같습니다!bb 만약에 feature에서 shared로 함수가 이동하게 되면 이동 히스토리도 같이 관리하게 되는지 아니면 공유만 하는 정도로 마무리되는지 궁금합니다
오 놀랍게도 제가 지금 사용 중인 폴더 구조와 꽤 유사하네요
저는 스스로가 문제를 이해하고 해결하기 위한 방법을 찾는다면 좋은 거라고 생각합니다.
구조가 비슷한 게 자주 보인다는 것은 보통 둘로 나뉠 텐데요
1에서 2를 느끼면 괜찮은데, 아니라면 적합하지 않은 구조거나, 선택하는 순간에 망설이게 되거나, 구조에 큰 의미가 없을 수도 있다고 생각해요.
반면에 2는 무조건적으로 문제 해결 방안으로 직결되기 때문에 특징 파악도 빠르고, 이 글에 나온 ‘나만의 틀’을 잡을 수 있는 사람이라고 생각합니다.
실제로 적용하고 더 많은 것을 알게 될 수도 있으니
고민하신 부분이 실천까지 갈 수 있다면 좋겠네요