[React] 프로젝트 디렉토리 구조 도대체 어떻게 잡아야 되나요? - 고민하지 마세요🙃
지난 시간동안 다수의 React 프로젝트를 진행하면서 프로젝트를 빌드해 갈때마다 디렉토리 구조에 대해서 고민했습니다. 어떤 방법으로 디렉토리 구조를 잡을지는 언제나 어려웠으면 최선, 최고의 선택을 위해 고민하게되었습니다. 이 아티클에서는 해당 문제에 대해서 고민하며 얻게된 제 경험과 알아온 것들을 정리해보았습니다.
먼저, React 공식 페이지에서는 어떻게 프로젝트 디렉토리 구조를 잡으라고 하는지 살펴볼까요?
Ref. https://ko.reactjs.org/docs/faq-structure.html
React 프로젝트를 구조화하는 권장 방법이 있습니까?
React는 정해진 프로젝트 디렉토리 구조를 정하지 않습니다. 즉, 고려할 수 있는 생태계에서 인기 있는 몇 가지 일반적인 접근 방식이 있습니다.
React 팀에서는 공식문서에서 고려할 수 있는 몇 가지 일반적인 접근 방법을 소개합니다.
1. 기능 또는 경로 별 그룹화
프로젝트를 구조화하는 일반적인 방법 중 하나는 기능 또는 경로 별로 그룹화 된 폴더 내에서 CSS, JS 및 테스트를 함께 찾는 것입니다.
"기능"의 정의는 보편적이지 않으며 세분화 방법은 개발자의 선택에 달려있습니다. 따라서 누가 기능을 기준으로 분리하느냐에 따라 달라질 수 있죠.
src 폴더 아래에서 components, pages 폴더를 생성하고 그 안에서 기능별 또는 페이지별로 JS, CSS, Test 파일을 묶어 분류해본 경험이 있습니다. 저는 이 방식은 유지보수 관점에서 다른 사람들이 봤을 때 가장 이해기 쉽고, 서로 연관성이 있는 파일끼리 분리되어 있어 직관적인 구조라고 생각합니다. 하지만 구조가 복잡해 질 수록 각 폴더가 가지는 파일의 수가 너무 많이 늘어나게 되고 디렉토리의 뎁스(depth)가 깊어 질 수 있습니다. 따라서 가벼운 사이즈의 어플리케이션에서는 최적의 선택이라고 생각합니다.
2. 파일 유형별로 그룹화
프로젝트를 구조화하는 또 다른 인기있는 방법은 유사한 파일을 함께 그룹화하는 것입니다. React 공식문서의 예시는 아래와 같습니다.
어떤 개발자들은 더 나아가 프로덕트에서의 역할에 따라 구성요소를 분리하는 것을 선호합니다. 예를 들어, Atomic Design은 이 원칙에 기반한 설계방법론 입니다. 이러한 방법론을 엄격한 규칙을 따르는 것보다 유용한 예제라고 생각하는 것이 더 좋습니다.
저는 이런 경우 파일을 유형별로 묶는 방법을 적용하기 위해서 Atomic Design(https://bradfrost.com/blog/post/atomic-web-design/) 방법론을 기반으로 components 폴더와 Pages의 폴더 구조를 1:1 매핑하여 각 화면에서 주요하게 사용되는 component 들을 위치시키고 공통으로 사용되는 component의 경우에는 common 폴더에서 관리할 수 있도록 했습니다.(2019)
최근(2021)에는 common 폴더를 만들지 않고 components 폴더 바로 아래서 관리합니다.
3. 너무 많은 중첩을 피하십시오.
JavaScript 프로젝트의 깊은 디렉터리 중첩과 관련된 많은 문제점이 있습니다. 너무 많은 중첩은 파일 간 import 시 경로를 작성하거나 파일이 이동되는 경우 업데이트하기 어려워집니다.(첨부: 그러나 절대경로를 사용한다면 해결이 가능한 문제입니다.) 단계가 깊은 폴더 구조를 사용해야하는 확실한 이유가 없다면 프로젝트 내에서는 폴더 레벨을 3~4개 단계로 제한하는 것이 유지보수(관리) 차원에서 좋습니다. 물론 이 또한 React에서는 권장사항일 뿐이며 실제 프로젝트와 관련이 없을 수 있습니다.(주관적)
깊은 폴더 구조의 폴더 중첩을 고민해야 한다면, 최대한 공통 컴포넌트 쪼개는 노력를 하거나 꼭 해당 컴포넌트에서 유지해야하는 경우 해당 폴더 또는 해당 컴포넌트에서 작성함으로써 중첩을 피하는 노력을 했습니다.(2019)
최근 (2021)에는 폴더 중첩 문제에 고민하지 않습니다. 다수의 프로젝트를 진행하며 얻은 경험으로는 아무리 깊은 폴더의 중첩이 일어나더라도 5 level 이상 늘어나지 않았으며, 컴포넌트를 가져다 쓰거나 찾거나 할 때 문제가 되지 않았습니다. 또한, 오히려 명확한 분리/구분으로 각 컴포넌트의 독립성을 보장할 수 있었습니다.
4. 이 문제를 지나치게 고민하지 마세요.
이 문제(디렉토리 구조)에 대해서 너무 깊게 고민하지 말고 자신만의 방식으로 코드를 작성하라고 합니다. 그리고 완전히 이에 대한 해결책을 찾지 못했다면 모든 파일의 소스를 단일 폴더에서 보관하는 것에서 부터 시작해보라고도 합니다.(참조: 하나의 컴포넌트에 몰아서) 결국엔 일부 파일을 꼭 분리해야하는 시점이 오면 어떤 연관성을 가지고 파일을 분리하고 폴더 구조를 잡아야하는지 보일 수 있습니다. 일반적으로 자주 변경되는 파일은 서로 가깝게 유지하는 것이 좋으며 이 원칙을 "colocation"(연관있는 것은 가까이 위치시킨다.)이라고 합니다.
여러 React 프로젝트를 진행하면서 다양한 디렉토리 구성 방식에 대한 고민을 하게되겠지만 결국 React 공식문서에서 내려준 결론은 위 접근방식을 적절히 적용해보며 프로젝트 아키텍처 별로 다른 디렉토리 구성을 만들어 나가야 한다. 즉, "각각의 프로젝트는 각각 다른 형태의 디렉토리 구성을 가질 수 있다."라는 결론이 나왔습니다.
제 경험에서 각 도메인을 분리한 후 그 아래에서 페이지를 분리하는 방법을 사용하고, 그에 필요한 컴포넌트를 1:1 매핑한 형태의 구조를 가져가는 것이 유지 보수 관점에서 좋았으며 나중에 다시 보더라도 빠르게 예측가능했던 경험이 있습니다. 또한 hooks를 통해 비즈니스 로직 분리하고 Redex를 통해 어디서든 상태를 공유할 수 있도록 만들어 유지보수하기 쉬운 프로젝트를 만들어 나갈 수 있었습니다.