Dev-Tino 7주차(1):: 리액트 프로젝트 폴더 구조
최근에는 리액트에 대해 공부하고 있다. 아직까지 리액트를 본격적으로 배우지는 않았고, 리액트를 공부하는 데에 필요할 기본적인 지식을 공부하며 정리하는 데에 많은 시간을 쏟고 있다. 지금 이 포스트도 그 맥락이다. 리액트를 사용하기 위해서는 리액트의 구조에 대해 알아야 한다.
그 뿐만 아니라 우리는 ‘프로젝트 폴더 구조 설계’ 에 대해서도 공부해야 한다. 혼자 작업하는 것이 아니기 때문이다. 정리되지 않은 파일들은 분명 장기적인 개발에 방해가 된다. 프로젝트를 원활히 진행하고 유지 보수를 쉽게 하기 위해서는 폴더의 구조를 꼭 알아야 한다. (*공식에서는 기초 구조만을 제공할 뿐 꼭 지키길 바란다! 는 프로젝트 폴더 구조를 제공하지는 않는다. 이 때문에 프로젝트 폴더에 대해서는 하단의 글을 참고하여 작성하였다::
리액트 프로젝트 초기 폴더 구조
my-app
├── node_modules
├── public
├── src
├── .gitignore
├── package.json
└── README. md
처음 프로젝트를 생성하면 다음과 같은 항목이 자동으로 생성된다. ‘node-modules’, ‘public’, ‘src’는 폴더이고 .gitignore, package.json, README. md는 파일이다.
-node_modules
현재 프로젝트에 포함된 라이브러리들이 설치되어 있는 폴더로 보통 깃과 같은 저장소에 올릴 때에는 이 폴더를 함께 올리지 않는다.
-public
index.html과 같은 정적 파일이 포함되는 곳으로 컴파일이 필요 없는 파일들이 위치하는 폴더이다.
-src
리액트 내부에서 작성하는 거의 모든 파일들이 이 폴더 내부에서 작성되며, 이 폴더에 있는 파일들은 명령어에 따라 JS로 컴파일이 진행된다.
-.gitignore
깃에 포함하고 싶지 않은 파일의 이름 또는 폴더 등을 입력하는 파일이다. (*이 곳에 적어둔 파일은 git, github의 버전 관리 목록에 포함되지 않는다.)
-package.json
프로젝트에 관련된 기본적인 내용(프로젝트의 이름, 버전 등)과 라이브러리들의 목록이 포함되어있다. 라이브러리가 설치된 node_modules 대신에 이 package.json을 깃에 포함하여 올리게 되며, 후에 누군가가 프로젝트를 클론할 때 이 package.json에 적혀있는 라이브러리의 목록을 기준으로 npm에서 설치하게 된다.
-README. md
깃과 같은 저장소에 올릴 때 프로젝트에 대한 설명을 작성하는 곳. 해당 저장소에 진입하면 가장 먼저 띄워진다.
SRC 내부 폴더 구조
└─ src
├─ components
├─ assets
├─ hooks (= hoc)
├─ pages
├─ constants
├─ config
├─ styles
├─ services (= api)
├─ utils
├─ contexts
├─ App.js
└─ index.js
위에서 말했듯 이 폴더는 ‘리액트 내부에서 작성하는 거의 모든 파일’이 작성되는 곳이다. 이 폴더에 있는 파일들은 명령어에 따라 JS로 컴파일된다. 여러가지 폴더들과 App.js, index.js가 있는데, index.js는 리액트 프로젝트가 임시로 만들어준 HTML 템플릿이며, App.js는 컴포넌트를 정의하는 프로그램이다. (실제로 화면에 표시되는 내용은 대개 이 곳에서 정의된다.)
-components
재사용 가능한 컴포넌트들이 위치하는 폴더이다. 컴포넌트는 매우 많아질 수 있으므로 이 폴더 내부에서 하위 폴더를 더해 추가로 분류하는 경우가 많다.
-assets
이미지 혹은 폰트와 같은 파일들이 저장되는 폴더이다. 이미지와 같은 파일을 public에 직접 넣는 경우도 있는데, 둘의 차이는 컴파일시에 필요한지 여부이다. index.html 내부에서 직접 사용하여 컴파일 단계에 필요하지 않은 파일들은 public에, 컴포넌트 내부에서 사용하는 이미지 파일의 경우에는 assets 폴더에 넣어야 한다.
-hooks( =hoc)
커스텀 훅이 위치하는 곳이다.
-pages
react router 등을 이용하여 라우팅을 적용할 때 페이지 컴포넌트를 이 폴더에 넣어둔다.
-constants
공통적으로 사용되는 상수들을 정의한 파일들이 위치하는 폴더이다.
-styles
css 파일들이 포함되는 폴더이다.
-services (= api)
보통 api(*애플리케이션 프로그램 인터페이스, 프로그램을 작성하기 위한 일련의 부 프로그램) 관련 로직의 모듈 파일이 위치하며, auth와 같이 인증과 관련된 파일이 포함되기도 한다.
-utils
정규표현식 패턴이나 공통함수 등 공통으로 사용하는 유틸 파일들이 위치하는 폴더이다.
-contexts
contextAPI를 사용할 때 관련 파일들이 위치하는 곳으로, 상태 관리를 위해 contextAPI 대신 redux를 사용할 경우 폴더 이름을 store로 사용하기도 한다.
단체 프로젝트를 할 때의 프로젝트 폴더 구조
본 게시글은 https://bttrthn-ystrdy.tistory.com/91 를 참고한다::
초급 구조:
맨 처음 create-react-app을 실행하면 src에는 아무 폴더도 없다. 이 때 많은 경우, src 폴더 안에 ‘componenets’ 폴더와 ‘hooks’ 폴더를 만든다고 한다. 굉장히 간단한 폴더 구조이지만 컴포넌트 개수가 10-15개 미만의 작은 프로젝트에서 사용하기에 나쁘지 않은 방법이다.
-Hooks
프로젝트에서 사용하는 모든 커스텀 hook(*함수 컴포넌트에서 React state와 생명 주기 기능을 연동-hook into-할 수 있게 해주는 함수이다.)을 저장하기 위한 폴더이다. 거의 모든 프로젝트는 한 개 이상의 커스텀 hook이 있고, 이러한 hook을 전부 저장할 수 있다면 유용하기 때문에 프로젝트 규모와 상관없이 도움이 된다.
-Components
간단한 폴더 구조에서는 전체 애플리케이션의 모든 컴포넌트가 컴포넌트 폴더에 담기기 때문에 매우 이해하기가 쉽다. 프로젝트의 컴포넌트가 10-15개를 넘어가며 프로젝트의 덩치가 커지면 컴포넌트 폴더를 관리하기가 굉장히 어려워질 수 있기 때문에, 컴포넌트를 여러 폴더에 분산시키고, 폴더 구조에 더 많은 구조를 부여하게 된다. 하지만 소규모 프로젝트에서는 이렇게 복잡하게 만들지 않고도 단일 컴포넌트 폴더만으로 충분하다.
-Tests
마지막 폴더인 테스트 폴더에는 모든 테스트 코드가 들어있다. 일반적으로 이러한 소규모 프로젝트(테스트 코드를 전혀 작성하지 않은 경우 등…)에는 모든 테스트를 하나의 폴더에 두는 경우가 있다. 보통은 소규모 프로젝트라면 이런 방법도 괜찮으나, 프로젝트 규모가 커진다면 다른 방법을 사용하는 것이 더 좋다.
장점
간단한 폴더 구조, 단순하나, 기능적인 측면에서 좋지 않다.
단점
사진, 유틸리티 함수, React 컨텍스트와 같은 객체를 어떻게 처리할지에 대해 사용자가 정할 수 있는 여지를 둔다. 소규모 프로젝트에서는 보통 이러한 추가 파일이 많지 않기 때문에 src 폴더의 루트에 둬도 괜찮다. 그러나 프로젝트의 덩치가 커지면 금세 지저분해지므로, 소규모 프로젝트보다 큰 규모의 프로젝트에서는 최소한 중급 폴더 구조를 사용하는 것이 좋다.
중급 구조:
중급 구조는 기본적으로 수많은 폴더를 가지며, index.js와 같은 파일만 src 폴더의 루트에 두고, 나머지는 세분화하여 src 폴더 하위의 폴더에 담아두어야 한다. 프로젝트를 페이지 단위로 세분화하여 특정 페이지에 대한 모든 로직을 한 곳에 포함한다는 점이 이 폴더 구조와 간단한 폴더 구조의 또다른 중요한 차이점이다. 프로그램의 규모가 커지면 여러 폴더를 검색하고 관련없는 파일을 걸러낼 필요 없이 하나의 폴더에서 해당 페이지와 관련된 모든 데이터를 찾을 수 있다는 점이 정말 유용하다. 또, 테스트 코드가 테스트하는 특정 폴더와 파일에 맞게 위치가 조정된다. 이렇게 하면 테스트하는 코드를 더 쉽게 식별할 수 있다.
-Pages
중급 구조에서의 가장 중요한 변화이다. 애플리케이션의 각 페이지는 이 위치에 해당 페이지의 폴더가 있어야 한다. 이것에는 각 페이지의 단일 루트 파일(일반적으로 index.js)과 해당 페이지에 속하는 모든 파일이 페이지별 폴더가 있어야 한다. 예를 들어, 어떤 페이지의 로그인 페이지에 index.js 루트 파일과 LoginForm 컴포넌트, useLogin이라는 커스텀 훅이 있다고 하자. Login 컴포넌트와 useLogin hook은 유일하게 로그인 페이지에서만 사용되므로 전역 hook이나 컴포넌트 폴더가 아닌, 로그인 페이지 폴더에 저장해둔다. 이 간단한 폴더 구조의 이점은 단연 ‘페이지별 코드와 일반적인 전역 코드를 분리’할 수 있다는 점이다. 모든 관련 코드가 하나의 폴더에 모여있기 때문에 애플리케이션이 수행하는 작업을 더 쉽게 이해할 수 있다.
-Componenets
또다른 중요한 차이점은, 컴포넌트 폴더 아래에 하위 폴더를 두어 더 세분화했다는 점이다. 이러한 하위 폴더는 컴포넌트를 하나의 커다란 덩어리로 묶기보다는 여러 그룹으로 분리해두기 때문에 꽤 유용하다. 위의 예시에서는 버튼, 모달, 카드 등의 사용자 인터페이스(UI) 요소가 포함된 ui 폴더가 포함되어 있다. 체크박스, input, 날짜 선택 등, form과 관련된 부분을 분리해둘 수도 있다. 컴포넌트 폴더는 프로젝트의 요구 사항에 맞춰 적절하게 조정하고 세분화할 수 있지만, 더 복잡한 컴포넌트들이 페이지 폴더에 많이 있기 때문에 컴포넌트 폴더가 너무 커지지 않게 하는 것이 이상적이라 할 수 있다.
-Hooks
Hooks 폴더는 초급 폴더 구조와 크게 다르지 않다. 위 폴더와 비슷하게 커스텀 훅을 저장하는데, 이 자료 구조 방식에서는 ‘애플리케이션의 모든 훅을 저장’하는 것이 아니라 여러 페이지에 걸쳐 사용되는 전역 hook만을 저장한다는 점이 특징이다. 특정 페이지에서만 쓰이는 hook은 해당 페이지 폴더에 저장되어 있기 때문이다.
-Assets
프로젝트의 모든 사진, css 파일, 폰트 파일 등은 assets 폴더에 저장한다. 코딩과 관련 없는 모든 파일을 이 폴더에 보관한다.
-Context
많은 페이지에서 사용되는 React context 파일을 context 폴더에 저장한다. 사이즈가 조금 더 큰 프로젝트에서 작업할 때 애플리케이션 전체에서 여러 컨텍스트를 사용할 가능성이 높기 때문에, 단일 폴더에 context 파일을 전부 가지고 있는 것이 특히 유용하다. Redux와 같은 다른 전역 데이터 스토어를 사용하는 경우 Redux 파일을 저장하는 폴더로 해당 폴더를 바꿀 수 있다.
-Data
데이터 폴더는 assets 폴더와 비슷하지만 프로그램에서 사용되는 정보(store 아이템, 테마 정보 등)가 포함된 JSON 파일 같은 데이터를 저장하는 데에 사용된다. 또한 전역으로 사용하는 상수 변수가 포함된 파일도 데이터 폴더의 하위 디렉토리에 보관할 수 있다. 데이터 폴더는 환경 변수 등 상수를 많이 사용하는 경우에 유용하다.
-Utils
유틸리티 폴더는 첫 번째 폴더 구조에 없는 새로운 폴더이다. 포맷팅(*어떤 형식으로 입출력할지?) 함수 등 모든 유틸리티 기능은 이 폴더를 사용한다. 유틸리티 폴더는 꽤 단순하기 때문에, 이 안에 있는 파일들도 전부 단순해야 한다. 사이드 이펙트(*부작용, 예상하지 못하는 상황에서 생기는 문제, 본인이 짠 코드가 예상하지 못하는 문제를 발생시키는 것.)가 있는 코드의 배치는 신중히 고민하고 결정해야 한다.
장점
각 파일은 고유의 폴더가 있다는 점이 두 번째 폴더 구조의 가장 큰 장점이다. src 루트 홀더에는 다른 파일이 거의 없어야 한다. 이러한 구조를 이용하면 일반적으로 코드를 이해하고 작성하거나 읽는 작업이 더 쉬워지며, 공용 컴포넌트와 hook 등의 디렉토리에 보관하는 전역 코드의 양이 줄어든다는 장점이 있다. 프로젝트의 덩치가 커짐에 따라 함께 사용하는 파일들을 함께 저장해두는 것이 더 중요해진다.
단점
이 방식의 가장 큰 단점은 애플리케이션이 커지면 커질 수록 페이지 폴더가 그 가치를 잃기 시작한다는 부분이다. 애플리케이션에 페이지가 많아지면 하나의 기능을 단순히 한 페이지에서 사용하는 게 아니라 여러 페이지에서 사용할 가능성이 점점 더 커지기 때문이다. 이렇게 되면 페이지 폴더의 사용 빈도가 줄고, 코드를 페이지 폴더에서 다른 폴더로 재배치해야 하기 때문에 다른 파일이 길어지게 된다.
[참고 자료]
-https://bttrthn-ystrdy.tistory.com/91
-https://velog.io/@bjgeumgang/React%EC%9D%98-%ED%8F%B4%EB%8D%94%EA%B5%AC%EC%A1%B0
- 카테고리
- #기타
댓글 0
추천 포스트