이롭게 현명하게

[React] 리액트 폴더 구조 본문

웹 개발/React

[React] 리액트 폴더 구조

dev_y.h 2025. 10. 31. 18:06
728x90
반응형

본 포스팅은 리액트 18 환경에서 작성되었습니다.

 


 

목차

리액트 기본 폴더 및 파일

src 내부 폴더 구조

[번외] package.json

 


 


[리액트 기본 폴더 및 파일]

프로젝트를 진행하다 보면 관리해야 할 파일들이 늘어난다.

파일들을 효율적으로 관리해야 하기 때문에 폴더의 구조를 잘 잡아야 한다.

 

24년 가지는 CRA를 사용하여 프로젝트를 구성했다.

하지만 2025년 2월 14일 리액트 공식 블로그에 CRA 사용을 중단한다는 글이 올라왔다.

그래서 vite를 사용하여 리액트 환경을 구성한다.

 

이 글에서는 타입스크립트를 기준으로 설명하겠습니다.

https://devyihyun.tistory.com/230

 

[React] vite로 리액트 설치하기

목차 create-react-app 지원 종료vite를 사용하는 이유vite 시작하기 https://devyihyun.tistory.com/168 [React] 리액트 시작하기 / 리액트 설치 / 개발환경목차 작업환경 준비하기Node.js 설치하기yarn 설치하기vscode

devyihyun.tistory.com

 

https://devyihyun.tistory.com/168

 

[React] 리액트 시작하기 / 리액트 설치 / 개발환경

목차 작업환경 준비하기Node.js 설치하기yarn 설치하기vscode 설치하기git for windows 설치하기리액트 환경설정 리액트 환경을 설치하는 CRA가 2025년 2월 14일에 종료되었습니다.npx create-react-app 대신 vite

devyihyun.tistory.com

 

 

아래는 vite로 생성한 리액트 프로젝트에서 기본적으로 설치되는 폴더 및 파일들이다.

react-project/
├── node_modules/
├── public/
├── src/
├── .gitignore
├── index.html
├── package.json
├── README.md
├── tsconfig.json
├── vite.config.ts

 

vite로 설치한 프로젝트

 

<node_modules>

install을 실행할 때 자동으로 생성된다.

노드 패키지 관리자 (npm)가 리액트 프로젝트에 필요한 dependcies를 보관하는 저장 디렉터리 역할을 한다.

  • 프로젝트에서 설치한 모든 패키지가 들어있는 폴더
  • 용량이 크고 자동 설치 가능
  • git 에는 올리지 않는다. (.gitignore로 제외)
  • 이 폴더가 없거나 삭제되었다면 install 하면 된다. 

 

<pubilc>

  • 정적 파일 보관 폴더(리소스 파일)
  • favicon, 이미지 등을 넣는다.
  • 빌드 시 수정 없이 그대로 복사된다.
  • ex) public/images/test.png 서버에서 → url로 접근 가능
  • 실제 서비스 배포 시 서버에서 접근 가능한 리소스는 대부분 public 폴더에 위치한다.

 

<src>

  • 애플리케이션의 실제 소스 코드가 위치하는 폴더
  • 리액트 컴포넌트, 스타일, 훅 등
  • main.tsx에서 App.tsx를 렌더링 하며 앱이 시작된다.
src/
├── components/      # 공통 UI 컴포넌트
├── pages/           # 라우팅 되는 페이지 컴포넌트
├── hooks/           # 커스텀 훅
├── assets/          # 이미지,폰트 등
├── utils/           # 공통 유틸 함수
├── App.tsx          # 루트 컴포넌트
├── main.tsx         # 진입점
  • src
    • assets
      • 이미지, 글꼴 및 기타 정적 리소스가 포함되어 있다.
    • main.tsx / main.jsx
      • React 앱의 진입점으로 루트 컴포넌트(App.ts)를 렌더링 하고, 이를 index.html에 주입하며 React의 업격한 모드와 구성을 설정하는 역할
    • app.tsx / app.jsx
      • 애플리케이션의 ui 구조와 로직을 정의하는 주요 React 구성 요소
      • main.js 내부에서 렌더링 되며 다른 구성 요소의 루트 구성요소로 사용된다.
      • src 내의 공통 폴더

 

<.gitignore>

  • Git에 커밋되지 않도록 무시할 파링 목록 지정
  • push를 해도 .gitignore 파일에 작성된 폴더와 파일은 올라가지 않는다.
  • node_modules, dist, env 등 민감하거나 용량이 큰 파일 제외

 

<index.html>

  • 리액트 앱의 단일 HTML 템플릿
  • <div id="root"> </div>가 리액트 앱이 렌더링 되는 곳
  • main.tsx가 사용되는 곳

 

<package.json>

  • 프로젝트의 메타 정보 및 의존성 리스트가 들어있다.
  • Git 저장소에 올라가면 팀원들이 이 파일을 기준으로 npm install을 할 수 있다.

 

<README.md>

  • 프로젝트 소개 및 사용 방법 등을 적는 문서
  • 깃과 같은 저장소에 올릴 때 프로젝트에 대한 설명을 작성하는 곳
  • 해당저장소에 진입하면 가장 먼저 띄워진다.

 

<tsconfig.josn>

  • 타입스크립트 프로젝트 설정 파일

 

<vite.config.ts>

  • vite의 설정 파일
  • ex) 플러그인 추가, 환경 변수 관리 등

 

<App.tsx 또는 App.jsx>

  • 앱의 루트 컴포넌트
  • 전체 앱의 레이아웃, 라우터, 전역 Provider 등이 정의된다.

 

<main.tsx 또는 main.tsx>

  • 앱의 진입점
  • React.DOM.createRoot로 App.tsx를 DOM에 렌더링 한다.
  • ReactRouter 사용 시 <BrowserRouter>로 App을 감싼다.
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'

ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<App />
</React.StrictMode>,
)

 

<index.css, App.css>

  • 전역 및 컴포넌트용 CSS 파일
  • 필요에 따라 테일윈드, SCSS 등으로 대체 가능

[src 내부 폴더 구조]

src/
├── assets/
├── components/
├── pages/
├── hooks/
├── utils/
├── routes/
├── layouts/
├── stores/
├── services/
├── style/
├── App.tsx
├── main.tsx
폴더명 용도
assets/ 이미지, 폰트, SVG 등 정적 리소스
components/ 재사용 가능한 작은 단위 UI 컴포넌트
pages/ 라우팅 단위 페이지 (한 화면 단위)
hooks/ 로직 재사용을 위한 커스텀 훅 (useXXX) 모음
utils/ 유틸 함수, 포맷터, 헬퍼 함수
routes/ 라우터 설정 관련 파일(예 : React Router)
layouts/ 페이지 공통 레이아웃 컴포넌트
stores/ 상태 관리(예 : Zustand,Recoil, Redux)
services/ API 요청 로직 (axios, fetch) 등 네트워크 관련 환경
style/ css 파일들이 포함되는 폴더

 

assets

  • 이미지, 폰트, 비디오, json 파일 등 미디어 파일들을 모아두어 저장하는 곳
  • 컴포넌트 내부에서 사용하는 이미지 파일인 경우 assets 폴더에 위치시켜야 한다.
  • public과 차이점 : 컴파일 시에 필요한지 여부
    • favicon과 같이 index.html 내부에서 직접 사용하여 컴파일 단계에서 필요하지 않은 파일들은 public에

 

components

  • 재사용 가능한 컴포넌트들이 위치하는 폴더
  • 컴포넌트는 많아질 수 있기 때문에 이 폴더 내부에서 하위 폴더로 추가로 분류하는 경우가 많다.
  • 공통 컴포넌트 관리(ex 헤더, 푸터, nav 등)

 

pages

  • react router 등을 이용하여 라우팅을 적용할 때
  •  페이지 단위의 컴포넌트 폴더로 구성
  • 로그인 페이지 - Login.tsx, login.css
  • 홈페이지 - Home.tsx, home.css

 

<components vs pages>

  • components : 여러 페이지에 동시에 사용되는 컴포넌트의 경우
  • pages : 해당 페이지 내에서만 사용하는 컴포넌트의 경우

 

hooks(=hocs)

  • 커스텀 훅이 위치하는 폴더
  • 함수형 컴포넌트를 사용하면서 커스텀 훅을 모듈화 하여 담아놓는 폴더

 

utils

  • 정규 표현식 패턴이나 공통함수 등 공통으로 사용하는 util 파일들이 위치하는 폴더
  • 상수나 공통함수, 유틸리티

 

layouts

  • 헤더, 푸터 등 프로젝트 전체에서 사용할 수 있는 레이아웃이 포함

 

stores

  • 상태에 저장하고 관리할 정보가 많은 대형 프로젝트에서 사용
  • 전역 상태 관리 라이브러리를 사용하면서 데이터를 저장하고 모듈화 해서 관리하는 폴더

 

services(=api)

  • api 관련 로직의 모듈 파일
  • auth와 같이 인증과 관련된 파일이 포함

 

style

  • css 파일들이 포한되는 폴더
    • scss 사용 시
      • react.scss → css 초기화
      • common.scss → 공통으로 사용하는 css 속성 정의
    • styled component 사용 시
      • GlobalStyle.js → css 초기화
      • theme.ts → 공통으로 사용하는 css 속성 정의 이외에 media.js 등등 다양한 css 파일을 속성에 맞게 분류하여 모듈화

 

 


[번외] package.json

{
  "name": "react-project",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "tsc -b && vite build",
    "lint": "eslint .",
    "preview": "vite preview"
  },
  "dependencies": {
    "react": "^18.3.1",
    "react-dom": "^18.3.1"
  },
  "devDependencies": {
    "@eslint/js": "^9.15.0",
    "@types/react": "^18.3.12",
    "@types/react-dom": "^18.3.1",
    "@vitejs/plugin-react": "^4.3.4",
    "eslint": "^9.15.0",
    "eslint-plugin-react-hooks": "^5.0.0",
    "eslint-plugin-react-refresh": "^0.4.14",
    "globals": "^15.12.0",
    "typescript": "~5.6.2",
    "typescript-eslint": "^8.15.0",
    "vite": "^6.0.0"
  }
}

package.json

 

dependencis

  • 리액트를 사용하기 위한 모든 패키지 리스트
  • 실제 코드는 node_modules 폴더에 존재한다.

 

script

  • start : 프로젝트 development mode(개발 모드) 실행을 위한 명령어 npm run start
  • build : 프로젝트 production mode(배포 모드) 실행을 위한 명령어, 서비스 상용화, npm run build

 

<node.modules와 package.json 에서 이중으로 패키지를 관리하는 이유>

  • 실제 내가 작성한 코드, 내가 설치한 패키지는 내 로컬에만 존재
  • github에 올릴 때 내가 작성한 코드와 함께 package.json(추가로 설치한 패키지)를 넘긴다.
  • 다른 사람이 그것을 pull 받아서 npm install만 입력하면 package.json에 기록되어 잇는 패키지의 이름과 버전 정보를 확인하여 자동으로 설치한다.
  • 이때, github에 올릴 때 node_modules는 올리면 안 되는데(불필요한 용량차지) .gitignore 파일에 github에 올리고 싶지 않은 폴더와 파일을 작성할 수 있다.

 

<package-lock.json과 yarn.lock>

[공통점]

  • 프로그래머가 관리할 필요가 없고 npm이나 yarn이 알아서 관리해 주는 파일들
  • lock 파일은 해당 프로젝트에 설치한 패키지, 그 패키지와 관련된 모든 패키지의 버전 정보를 포함한다.

 

[package-lock.json]

  • npm install을 하면 package.json을 기준으로 node_modules가 설치된다.
  • package.json에서 버전 앞에 ^가 붙은 경우 최신 패치 버전이 자동으로 설치된다.
  • 캐럿과 틸드
    • ^ (캐럿):x.y.z 중 x 이하 하위호환성이 보장되는 범위 내에서 버전 업데이트
    • 예 : ^18.4.2 → 18.4.2≤ 19.0.0
    • ~(틸드) : x.y.z 중 z 범위 내에서 버전 업데이트
    • 예 : ~18.4.2 → 18.4.2 ≤ 18.5.0
  • 라이브러리는 계속해서버그가 수정되고 패치된다.
  • 만약 npm install을 통해 내가 사용하던 버전이 아닌 최신 버전의 라이브러리가 설치된다면 라이브러리의 내용이 바뀌어 내 프로젝트에 문제가 생길 수 있다.
    • 이유
    • 라이브러리 A를 설치했다.
    • A : ^4.18.2
    • 만약 npm install을 하면 내가 사용하던 버전 그 이상의 버전으로 설치된다.
    • A : ^4.18.2라는 정보가 내가 설치했을 때의 라이브러리의 내용과 다를 수 있다.
  • 이것을 방지하기 위해 라이브러리를 설치했을 때의 시점에 내용이 보존되어야 한다.
  • 이 문제를 방지하기 위해 사용하는 것이 package-lock.json이다.
  • package-lock.json은 내가 사용했던 그 버전 그 상태 그대로 무조건 받게 끔 잠금을 해놓는 것이다.
  • Github에 올릴 때는 package.json과 package-lock.json을 함께 포함시켜야 한다. → 동일한 환경 보장

 

[yarn.lock]

  • yarn install은 yarn.lock을 기준으로 node_modules가 설치된다.
  • npm과 yarn은 서로 다른 패키지 관리 시스템이다.
  • 그래서 둘 다 사용하면 충돌 위험이 있다.
  • package-lock.json과 yarn.lock을 동시에 사용하는 것은 금지
  • 팀 프로젝트에서는 npm 또는 yarn 중 하나로 통일

 

[yarn을 사용하는 이유]

  • yarn은 의존성 추적이 더 철저하다
  • react-swiper라는 라이브러리가 있다.
  • 이 라이브러리 안에는 swiper.js라는 라이브러리를 사용 중이다.
  • 즉 swiper.js라는 라이브러리를 사용하여 react-swiper 라이브러리를 만든 것이다.
  • react-swiper라는 라이브러리 설치
  • npm은 내부에서 사용하는 swiper.js를 자동으로 설치하지 않을 수 있다. 그래서 npm install swiper.js으로 수동으로 설치해야 한다.
  • yarn은 yarn add react-swiper를 하면 의존 라이브러리까지 자동으로 설치한다.

 

[npm에서 yarn으로 변경하고 싶을 때]

  • package.json은 절대로 삭제하면 안 된다.
  • node_modules와 package-lock.json 삭제
  • yarn install 실행 → 자동으로 yarn.lock 생성
  • 단 이때부터는 npm install 대신 yarn add로 패키지를 설치해야 한다.

 

 


잘못된 정보는 댓글에 남겨주시면 감사하겠습니다!😊

댓글과 좋아요는 큰 힘이 됩니다!

 

더보기

 

728x90
반응형
Comments