폴더구조의 중요성
저는 개발 프로젝트에서 폴더의 구조를 정하는 것에 항상 고민을 깊게 하는 편입니다..
체계적이고 잘 정돈된 폴더구조는 장기적으로 유지보수성과 코드생산성을 끌어올려준다고 믿기 때문인데요
가장 커다랗게 체감했던 것은 여러명이서 진행하는 프로젝트였던 PLIP 프로젝트의
폴더 구조를 기획하고 개발을 진행하던 과정에서 였는데요
짤막한 홍보를 하자면 배포 url은 다음과 같습니다.
다음 사진은 이 당시 PLIP 프로젝트의 폴더구조를 만들때에 제가 생각하고 짰던 방식입니다.
그 당시에 저는 "같은 성격을 가진 파일은 한폴더에 모여있어야한다."라고 믿었습니다.
그래서 이 프로젝트의 폴더구조도 그와 같이 작성되어있는 것을 볼 수 있습니다.
이런식으로 구조화된 프로젝트의 장점은 명확합니다.
어디에 어떤 코드가 위치할지 명확하게 예측가능하며 같은 성격의 코드들이 하나로 응집되어있기때문에
프로젝트의 특정 부분에서 문제가 발생한다면 단번에 문제영역을 특정하여 좁힐 수 있다는 것이에요.
또한 내가 필요로 하는 코드가 어디에 위치하고 있을지 예상하는 것이 쉽다는 것도 장점입니다.
이렇게 작성되었을 때 가장 유용했던 것은 특정한 기능이 전체적으로 수정될 필요성이 있을 때에
수정이 용이했다는 것입니다.
예를 들어 프로젝트를 진행하면서
저는 fetch로 작성된 api 호출 코드 전체를 인터셉팅 기능 등 axios에서 제공되는 강력한 기능들을 활용하기 위해
axios로 마이그레이션을 수행하였었습니다.
그 과정에서 api 호출 코드들은 모두 queries 폴더에 응집되어있었기 때문에
큰 어려움 없이 모든 api 호출 코드들을 누락 없이 변경할 수 있었습니다.
반면 단점은?
이러한 방식으로 작성된 프로젝트는 제 개인적인 생각으로는
규모가 작은 프로젝트일때에 적절한 방식이라고 생각합니다.
규모가 작은 프로젝트에서는 파일의 수가 많지 않기 때문에
폴더와 폴더간을 오가는 중에 발생하는 개발자의 컨텍스트 스위칭이 크지 않습니다.
물론 cmd + p와 같이 IDE에서 직접 폴더명을 기반으로 트래킹해도 되지만요
하지만 이런 방식은 프로젝트 규모가 커지고 관리하는 파일이 많아질수록 어려워지는데요
폴더 하나를 열었을때 생기는 엄청난 스크롤들을 내려가면서
내가 원하는 폴더를 찾아가는것은 생각보다 시간을 꽤 잡아먹는 일이 되곤 합니다.
사실 재사용되지않고 특정 페이지에서만 사용되는 로직인데도 불구하고
관심사를 응집시키기 위해 개발자는 한없는 스크롤을 감수해야합니다.
내가 필요한 파일이 한곳에 모여있으면 개발생산성이 훨씬 좋아지지않을까요?
코로케이션
주로 colocation은 가까운곳에 파일을 배치하는 것이라는 의미로 많이 사용되는 듯 합니다.
제가 회사에 입사하고 가장 경악했던 부분은 페이지 인덱싱만 수행해야할
next.js의 pages 폴더에 component , utils 와 같은 성격의 폴더와 파일이 잔뜩 들어가있었던 것이었습니다.
그덕분에 실제로 사용되는 페이지는 30여개에 불과한 반면
빌드 시 SSG 되는 페이지는 400여개를 넘는 수준으로 운영되고있었습니다.
지금도 pages 폴더의 파일들은 인덱싱만 수행해야한다는 믿음에는 이견이 없지만
이와 같이 서로 같이 쓰이는 파일들은 가까운곳에 배치한다라는 발상 자체에는 생각해볼 여지가 있었습니다.
https://kentcdodds.com/blog/colocation
이 글이 많은 영감을 줬는데요
실제로도 개발을하면서 가까운곳에 파일을 배치하는 것은 대부분의 경우에서 매우 유용했습니다.
예를 들어서
sign-up-page.tsx
sign-up-page.test.tsx
이 두 파일은 성격적으로는 전혀 다른 파일입니다.
하나는 페이지의 역할을 수행할 리액트 컴포넌트 파일이고
하나는 테스트를 수행하는 파일이기 때문입니다.
이러한 파일을 기존 방식과 같이 관심사대로 배치하게 되면
다음과 비슷한 폴더구조가 형성됩니다.
/__tests__/sign-up-page.test.tsx
/components/page/sign-up-page.tsx
그런데 사실 이렇게 되면 개발자는 sign-up-page이 테스트로 커버되고있는지
알기 위해서는 저 위에있는 __tests__ 폴더까지 올라가서 파일의 존재를 확인하는 수 밖에 없습니다.
게다가 사실 sign-up-page.test.tsx는 오로지 sign-up-page.tsx만을 위해 존재하는 테스트파일이기에
다른 곳에서 재사용되어야할 여지조차 없습니다.
이러한 경우는 제가 생각하였을 때 코로케이션을 적용하기 매우 적절한 상황 중 하나입니다.
즉 두 파일은 이렇게 배치되는 것이 유지보수에 더 유리합니다.
코로케이션의 딜레마
그런데 개발을 하다보면 이런 경우가 흔하게 발생하곤합니다.
처음에는 한곳에서만 쓰였는데 기획이 확장되면서 다른곳에서도 사용될 여지가 생기는 것들입니다.
코로케이션을 적용하면서 이부분이 가장 어려웠는데요
공통으로 쓰일것이 확실한 파일 / 특정 부분에서만 쓰일것이 확실한 파일들을 분류하는것은 매우 쉽지만
그 중간 어딘가의 회색지대에 있는 파일들의 배치가 아주 애매했습니다.
예컨대 전체 애플리케이션에서 단 두 군데에서만 공유해서 사용하는 파일이 있다면 어떨까요?
혹은 원래는 한곳에서만 사용했는데 기획이 확장되며 여러곳에서 참조하게되면 어떨까요?
저는 일단은 한곳에서만 사용하면서 만약 공유해야하는 시점이 오면
그때에서야 공통적으로 사용할 수 있게 분리하는 편입니다만 이부분이 참 어렵게느껴지는 것 같습니다.
결국 내가 선택한 폴더 구조
폴더구조를 정할 때에는 항상 상황에 맞는 선택을 하는 것이 중요한 것 같습니다.
추가로 제 방법이 절대적으로 옳은 것은 아닙니다만
폴더 자체가 라우팅의 기준이 되는 next.js에서 어떻게 코로케이션을 적용하면 좋을지 고민해본 결과
저는 이런 폴더 구조를 택하였습니다.
pages에서는 라우팅의 기준이 될 파일과 폴더만 생성하고
각 페이지에서 단발적으로 사용되는 컴포넌트 / 테스트 코드 / 유틸함수등은
외부에 만들어둔 폴더에 코로케이션을 적용하여 넣어두는 형식입니다.
이렇게 폴더구조를 잡았을 때에 느낄 수 있던 장점은 다음과 같은데요
1. pages 폴더의 역할이 명확해진다.
-> pages 폴더는 순수하게 라우팅을 수행하는 폴더로 관심사를 완전히 분리할 수 있었습니다.
따라서 불필요한 정보없이 라우팅에 관한 정보를 쉽게 찾을 수 있게되었어요
2. 각 페이지별로 Provider를 설정하기 쉬워진다.
개발을 하다보면 인증과 권한에 따라 접근이 가능한 페이지 / 불가능한 페이지를 구분해주어야하는 경우가 많습니다.
이런 경우 각 페이지마다 그 페이지에 필요한 프로바이더들이 잘 들어가있는지 쉽게 확인할 수 있어졌습니다.
마치며
베스트 프래티스는 뭘까요..
저도 정말 궁금합니다
'frontend' 카테고리의 다른 글
next.js , tailwindcss, path alias storybook 세팅하기 (2) | 2023.11.07 |
---|---|
제목은 일단 스토리북으로 하겠습니다 그런데 고민을 곁들인 (2) | 2023.10.31 |
radix와 framer-motion을 통합하고 exit animation을 주는 방법 (1) | 2023.10.03 |
radix 의 기본 focus css 제거하기 (0) | 2023.09.30 |
hotfix branch 전략으로 빠른 버그수정하기 (0) | 2023.09.23 |