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