Tech/React

[React] React 프로젝트의 파일 구조 설계하기

Lamue 2023. 9. 18. 12:39

프로젝트를 진행하다 보면 크기가 커질수록 관리해야할 파일은 늘어나고 이에 따라 각 파일들을 용도에 맞게 분류해야할 필요성을 느끼게 됩니다. 저도 최근에는 프로젝트를 시작하기 전에 필요한 폴더들을 미리 생성하고 전체적인 프레임을 설계한 이후 개발을 진행하고 있습니다.

이번 포스팅은 리액트를 사용할 때 폴더의 구조를 어떻게 잡으면 좋을지에 대해 다뤄보겠습니다.

먼저 CRA를 설치했을 때 기본적으로 설치되는 폴더 및 파일들의 역할에 대해서 간단히 살펴보겠습니다.

 

CRA 초기 폴더구조

my-app

├── node_modules

├── public

├── src

├── .gitignore

├── package.json

├── package-lock.json

└── README.md

 

  • node_modules
    현재 프로젝트에 포함된 라이브러리들이 설치되어 있는 폴더입니다.
    보통 깃과 같은 저장소에 올릴 때는 이 폴더를 함께 업로드 하지 않습니다.
  • public
    index.html과 같은 정적 파일이 포함되는 곳으로 컴파일이 필요 없는 파일들이 위치하는 폴더입니다.
  • src
    리액트 내부에서 작성하는 거의 모든 파일들이 위치하는 폴더입니다.
    이 폴더에 있는 파일들은 명령어에 따라 JS로 컴파일이 진행됩니다.
  • .gitignore
    깃에 포함하고 싶지 않은 파일의 이름 혹은 폴더등을 입력하는 파일입니다.
    push를 할 경우 .gitignore 파일에 작성된 폴더와 파일은 올라가지 않습니다.
  • package.json
    프로젝트에 관련된 기본적인 내용(프로젝트의 이름, 버전 등)과 라이브러리들의 목록이 포함되어 있습니다.
    라이브러리가 설치된 node_modules 대신에 이 package.json을 깃에 포함하여 올리게 되며 후에 누군가가 프로젝트를 클론할 때 이 package.json에 적혀있는 라이브러리의 목록을 기준으로 npm에서 설치하게 됩니다.
  • package-lock.json (or yarn.lock)
    프로그래머가 관리할 필요가 없고 npm 이나 yarn이 알아서 관리해주는 파일들의 정보가 포함되어 있습니다. 

    lock파일은 해당 프로젝트에 설치한 패키지 , 그 패키지와 관련된 모든 패키지의 버전정보를 포함합니다.
  • README.md
    보통 깃과 같은 저장소에 올릴 때 프로젝트에 대한 설명을 작성하는곳으로 해당 저장소에 진입하면 가장 먼저 띄워집니다.
왜 node.modules과 package.json에서 이중으로 패키지를 관리할까?
실제 내가 작성한 코드, 내가 설치한 패키지는 내 로컬에만 존재합니다.
프로그래머는 작성한 코드를 github에 올릴 때 내가 작성한 코드와 함께 pacakge.json(추가로 설치한 패키지)를 전달합니다. 다른 사람이 그것을 (pull) 받아서 npm install만 입력하면 package.json에 기록되어 있는 패키지의 이름과 버전 정보를 확인하여 자동으로 설치할 수 있습니다.
작성한 코드를 github에 올릴 때 node.modules는 불필요한 용량을 차지하기 때문에 업로드 하지 않습니다.
이 때 .gitignore파일에 github에 올리고 싶지 않은 폴더와 파일을 작성할 수 있습니다.

 

src 내부 폴더구조

 src

 ├─ components

 ├─ assets 

 ├─ hooks (= hoc)

 ├─ pages

 ├─ constants

 ├─ config

 ├─ styles

 ├─ services (= api)

 ├─ utils

 ├─ contexts

 ├─ App.js

 └─ index.js

 

  • components
    재사용 가능한 컴포넌트들이 위치하는 폴더입니다.
    컴포넌트는 매우 많아질 수 있기 때문에 이 폴더 내부에서 하위폴더로 추가로 분류하는 경우가 많습니다.
  • assets
    이미지 혹은 폰트와 같은 파일들이 저장되는 폴더입니다.
    이미지와 같은 파일들을 public에 직접 넣는 경우도 있는데 둘의 차이는 컴파일시에 필요한지 여부입니다.
    파비콘과 같이 index.html내부에서 직접 사용하여 컴파일 단계에서 필요하지 않은 파일들은 public에 위치시킵니다.
    반면, 컴포넌트 내부에서 사용하는 이미지 파일인 경우 이 assets 폴더에 위치시킵니다.
  • hooks (= hoc)
    커스텀 훅이 위치하는 폴더입니다.
  • pages
    react router등을 이용하여 라우팅을 적용할 때 사용되는 페이지 컴포넌트를 이 폴더에 위치시킵니다.
  • constants
    공통적으로 사용되는 상수들을 정의한 파일들이 위치하는 폴더입니다.
  • config
    config 파일이 많지 않은 경우 보통 최상단에 위치시켜놓지만 여러개의 config 파일이 있을 경우 폴더로 분리하기도 합니다.
  • styles
    css 파일들이 포함되는 폴더입니다.
  • services (= api)
    보통 api관련 로직의 모듈 파일이 위치하며 auth와 같이 인증과 관련된 파일이 포함되기도 합니다.
  • utils
    정규표현식 패턴이나 공통함수 등 공통으로 사용하는 유틸 파일들이 위치하는 폴더입니다.
  • contexts
    contextAPI를 사용할 때 관련 파일들이 위치하는 폴더입니다.
    contextAPI 대신 redux를 사용 할 경우 폴더 이름을 store로 사용하기도 합니다.
components vs pages
여러 페이지에서 동시에 사용되는 컴포넌트의 경우 components 폴더에서 관리합니다.
페이지 컴포넌트의 경우 pages 폴더에서 관리합니다.
해당 페이지 내에서만 사용하는 컴포넌트의 경우 해당 페이지 폴더 하위에서 관리하는 것이 좋습니다.

 

 

React 공식 홈페이지에서는 어떤 방식을 추천할까 ?

1. 기능 또는 경로 별 그룹화

프로젝트를 구조화하는 일반적인 방법 중 하나는 기능 또는 경로 별로 그룹화 된 폴더 내에서 CSS, JS 및 테스트를 함께 찾는 것입니다.

"기능"의 정의는 보편적이지 않으며 세분화 방법은 개발자의 선택에 달려있습니다.

해당 방식은 유지보수 관점에서 다른 사람들이 봤을 때 가장 이해기 쉽고, 서로 연관성이 있는 파일끼리 분리되어 있어 상당히 직관적인 구조입니다. 하지만 구조가 복잡해 질 수록 각 폴더가 가지는 파일의 수가 너무 많이 늘어나게 되고, 그 결과 디렉토리의 뎁스(depth)가 깊어 질 수 있습니다. 따라서 가벼운 사이즈의 어플리케이션에서 취하기 좋은 구조라고 생각됩니다. 

 

2. 파일 유형별로 그룹화

프로젝트를 구조화하는 또 다른 인기있는 방법은 유사한 파일을 함께 그룹화하는 것입니다. 

 

3. 너무 많은 중첩을 피하기

 JavaScript 프로젝트의 경우 디렉터리 중첩과 관련된 많은 문제점이 있습니다. 너무 많은 중첩은 파일 간 import 시 경로를 작성하거나 파일이 이동되는 경우 업데이트하기 어려워진다는 문제를 가집니다. (물론 절대경로를 사용한다면 해결이 가능합니다.)

단계가 깊은 폴더 구조를 사용해야하는 확실한 이유가 없다면 프로젝트 내에서는 폴더 레벨을 3~4개 단계로 제한하는 것이 유지보수(관리) 차원에서 좋습니다. 물론 이 또한 React에서는 권장사항일 뿐이며 실제 프로젝트에선 상황에 따라 유연하게 적용하는 것이 좋습니다. 

 

4. 이 문제에 대해 지나치게 고민하지 않기

이제 막 프로젝트를 시작하는 단계라면 파일 구조를 선택하는 것에 있어서 5분 이상 시간을 투자하지 마세요. 앞서 살펴본 접근법 중에 아무거나 선택하고 자신만의 방식으로 코드를 작성하면 됩니다. 만약 이에 대한 해결책을 찾지 못했다면 우선 모든 파일의 소스를 단일 폴더에서 보관하는 것에서 부터 시작해보세요. 이후 일부 파일을 꼭 분리해야하는 시점이 오면 어떤 연관성을 가지고 파일을 분리하고 폴더 구조를 잡아야하는지 보일 수 있습니다. 

 

 

마치며

지금까지 React 프로젝트를 진행할 때 사용할 수 있는 일반적인 파일 구조에 대해 소개하였습니다. 

 

여러 React 프로젝트를 진행하면서 다양한 디렉토리 구성 방식에 대한 고민을 하게되겠지만, 결국 React 공식문서에서 내려준 결론은 위 접근방식을 적절히 적용해보며 프로젝트 아키텍처 별로 다른 디렉토리 구성을 만들어 나가야 한다는 것이었습니다. 즉, "각각의 프로젝트는 각각 다른 형태의 디렉토리 구성을 가질 수 있다."라는 것입니다.

 

이렇게 컴포넌트 구조에는 정답이 없다보니, 여러가지 패턴들도 많이 존재합니다. 최근에는 Atomic Design을 적용한 파일 구조가 많은 개발자들에게 사랑받고 있다고 합니다. 향후 기회가 되면 Atomic Design에 대한 소개와 React에 적용하는 것과 관련된 글을 작성해보겠습니다. 

 

 

참고

https://velog.io/@sisofiy626/React-%EB%A6%AC%EC%95%A1%ED%8A%B8%EC%9D%98-%ED%8F%B4%EB%8D%94-%EA%B5%AC%EC%A1%B0 

 

[React] 리액트의 폴더 구조

프로젝트를 진행하다 보면 크기가 커질수록 관리해야할 파일은 늘어나고 이에 따라 각 파일들을 용도에 맞게 분류해야할 필요가 생깁니다.

velog.io

https://ko.reactjs.org/docs/faq-structure.html 

 

파일 구조 – React

A JavaScript library for building user interfaces

ko.legacy.reactjs.org

https://xtring-dev.tistory.com/entry/React-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-File-%EA%B5%AC%EC%A1%B0-%EB%8F%84%EB%8C%80%EC%B2%B4-%EC%96%B4%EB%96%BB%EA%B2%8C-%EC%9E%A1%EC%95%84%EC%95%BC-%EB%90%98%EB%82%98%EC%9A%94  

https://velog.io/@_seeul/React-%EB%A6%AC%EC%95%A1%ED%8A%B8%EB%A1%9C-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8%EB%A5%BC-%EC%A7%84%ED%96%89%ED%95%A0%EB%95%8C-%EC%96%B4%EB%96%BB%EA%B2%8C-%ED%8F%B4%EB%8D%94-%EA%B5%AC%EC%A1%B0%EB%A5%BC-%EC%9E%A1%EB%8A%94%EA%B2%83%EC%9D%B4-%EC%A2%8B%EC%9D%84%EA%B9%8C