리액트의 폴더 구조

cjkangme·2023년 11월 6일
0

react

목록 보기
1/6

리액트 프로젝트를 시작할 때 가장 먼저 해야하는 것 중 하나가 바로 폴더 구조를 결정하는 것이다.

폴더 구조가 잘 설계 되었다면 프로젝트 규모가 커져도(폴더와 파일이 많아져도) 원하는 폴더, 파일을 찾아가는 것이 어렵지 않을 것이다.

즉 폴더 구조는 클린 코드와 같이 가독성을 위해 중요한 요소이며, 코드의 유지 보수성을 증가시킨다.

대중적인 구조


출처: nz-m/SocialEcho 레포지토리

프로젝트마다 폴더 이름은 조금씩 다룰 수 있지만, 가장 많이 볼 수 있는 형태의 폴더 구조이다.

api

백엔드와 연결하는데 필요한 함수, 백엔드에서 받아온 파일을 처리하는 로직 등을 저장하고 있는 폴더

// 예시
export const axios = Axios.create({
  baseURL: process.env.BASE_URL,
});

assets

폰트, 이미지 등 컴포넌트 렌더링에 필요한 파일을 저장하는 폴더이다.

components

재사용 가능한 컴포넌트들을 모아 저장하는 폴더이다.

  • 최소단위의 ui 컴포넌트
  • 여러 모듈/페이지에서 공통적으로 사용하는 컴포넌트

일반적으로 프로젝트가 커질 수록 많은 컴포넌트가 필요해지기 때문에 하위 폴더를 통해 컴포넌트를 분류하여 가독성을 높인다.

hooks

커스텀 훅을 모아 저장한 폴더

[#]interfaces (=types)

타입스크립트 사용시에 Type으로 사용할 인스턴스를 정의해 둔 폴더

routes

서브 라우팅, private 라우팅 등의 라우트를 관리하는 폴더
프로젝트 전체에서 사용하는 환경 변수, 설정을 포함하여 config 폴더로 명명해 함께 관리할 수도 있다.

stores (≒ redux, context)

redux, mobx 등의 상태 관리 저장소를 사용할 경우 관련 파일을 모아 놓은 폴더
Context API를 사용할 경우 주로 context라고 한다.

styles

UI 스타일 적용에 필요한 color, font-size 등의 상수 값을 모아놓은 폴더

utils

어플리케이션에 필요한 각종 로직 함수를 모아놓은 폴더
수치 연산, 정규식 표현 함수 등이 포함된다.

view (≒ page, screen)

하나의 페이지, 레이아웃 등 컴포넌트 여러개가 쌓여 이루어지는 보다 큰 단위의 컴포넌트를 모아 놓은 폴더

한계

위와 같은 구조는 프로젝트 초기에도 큰 어려움 없이 적용할 수 있는 구조라는 장점이 있다.

그러나 프로젝트 규모가 점점 커져 페이지, 컴포넌트, 커스텀 훅, 로직 등이 늘어날 수록 한 폴더안에 존재하는 파일이 많아져 가독성이 저하된다는 한계가 있다.

이로인해 Bast Practice에서는 기능별 폴더구조를 사용할 것을 권장한다.

기능별 폴더구조

참고자료

기능별 폴더구조와 기존 폴더구조의 차이점은 앞서 설명한 폴더 구조를 각 기능별로 갖도록 한다는 것이다.

우선 기존의 components 폴더에는 전체 프로젝트 또는 여러 모듈이 공통으로 사용하는 최소 단위의 컴포넌트만 남겨 놓는다.

그리고 기존의 page 대신 features 폴더를 생성해 각 기능별로 하위 폴더를 갖게 한다.

기능별 하위 폴더의 구조는 다음과 같다.

src/features/awesome-feature
|
+-- api         # exported API request declarations and api hooks related to a specific feature
|
+-- assets      # assets folder can contain all the static files for a specific feature
|
+-- components  # components scoped to a specific feature
|
+-- hooks       # hooks scoped to a specific feature
|
+-- routes      # route components for a specific feature pages
|
+-- stores      # state stores for a specific feature
|
+-- types       # typescript types for TS specific feature domain
|
+-- utils       # utility functions for a specific feature
|
+-- index.ts    # entry point for the feature, it should serve as the public API of the given feature and exports everything that should be used outside the feature

이렇게 각 기능이 내부에서 사용하는 로직, 컴포넌트, 에셋 등을 하나의 폴더 안에서 관리 한다.

이렇게 되면 새로운 기능이 추가되더라도 공용 로직, 컴포넌트가 추가될 여지가 적으며, 새로운 기능 폴더를 생성하여 그 안에서 관리하면 된다는 장점이 있다.

다만 이는 프로젝트 규모가 작을 때 필요 이상의 복잡성을 유발할 수 있으므로, 프로젝트 규모를 고려해서 가장 효율이 좋은 방법을 선택하는 것이 좋을 것이다.

참고자료

깃허브 저장소

칼럼

0개의 댓글