프론트/React

[React] 프로젝트 폴더 생성 방법(Vite,CRA) 및 개발 vs 운영 환경

초코chip 2024. 10. 30. 17:55

최신 방식 - Vite

npm create vite@latest <프로젝트 이름> -- --template react

 

프로젝트 폴더 구성

my-app/

├── node_modules/           # 프로젝트 종속성 모듈

├── public/                 # 정적 파일 (CRA와 달리 HTML 파일 없음)

├── src/

   ├── assets/             # 이미지와 폰트 같은 정적 파일

   ├── App.css             # App 컴포넌트 스타일

   ├── App.jsx             # 메인 컴포넌트

   ├── main.jsx            # 엔트리 포인트 (ReactDOM.createRoot() 호출)

└── package.json            # 프로젝트 종속성 및 스크립트

└── index.html              # Vite의 메인 HTML 파일

└── vite.config.js          # Vite 설정 파일

└── README.md               # 프로젝트 설명 파일

 

 

Vite 기본 스크립트

"scripts": {

  "dev": "vite",                       // 개발 서버 실행 (ES 모듈 기반 서버)

  "build": "vite build",               // 프로젝트 빌드 (production 모드)

  "preview": "vite preview"            // 빌드 후 로컬에서 미리보기 서버 실행

}

  • dev: vite 명령어는 ES 모듈 기반의 Vite 개발 서버를 실행
    • CRA의 start 명령어와 동일한 역할을 하지만, 속도가 훨씬 빠르고 즉각적인 HMR을 지원
    • HMR: 코드가 수정될 때 페이지를 새로고침하지 않고도 브라우저에 변경 사항을 즉각 반영해주는 기능
  • build: vite build 명령어는 Vite의 빌드 프로세스를 통해 프로젝트를 프로덕션 모드로 빌드
    • 빌드 결과는 dist/ 폴더에 생성
  • preview: vite preview 명령어는 로컬 서버에서 빌드된 결과물을 미리 확인 가능
    • 이 서버는 정적 파일을 제공

 

기존 방식 - CRA (Create React App)

npx create-react-app <프로젝트 이름>

 

더보기

프로젝트 폴더 구성

my-app/

├── node_modules/          # 프로젝트 종속성 모듈

├── public/                # 정적 파일, HTML 파일 등이 위치

   ├── favicon.ico

   ├── index.html         # 메인 HTML 파일

   └── robots.txt

├── src/

   ├── App.css            # App 컴포넌트 스타일

   ├── App.js             # 메인 컴포넌트

   ├── App.test.js        # 기본 테스트 파일

   ├── index.css          # 전역 스타일

   ├── index.js           # 엔트리 포인트 (ReactDOM.render() 호출)

   ├── logo.svg           # 리액트 로고

   ├── reportWebVitals.js # 웹 성능 측정

   └── setupTests.js      # 테스트 설정

├── .gitignore

├── package.json           # 프로젝트 종속성 및 스크립트

└── README.md              # 프로젝트 설명 파일

 

CRA 기본 스크립트

"scripts": {

  "start": "react-scripts start",     // 개발 서버 실행 (Webpack Dev Server)

  "build": "react-scripts build",     // 프로젝트 빌드 (production 모드)

  "test": "react-scripts test",       // 테스트 실행 (Jest 사용)

  "eject": "react-scripts eject"      // Webpack 설정 파일 노출 (Eject)

}

  • start: react-scripts start 명령어는 개발 서버(Webpack Dev Server)를 실행
    • 기본적으로 localhost:3000에서 앱을 확인 가능
  • build: react-scripts build 명령어는 Webpack을 이용해 프로젝트를 프로덕션 모드로 빌드
    • build/ 폴더에 빌드된 파일들이 생성
  • test: react-scripts test 명령어는 Jest로 작성된 테스트를 실행
    • 기본적으로 .test.js 또는 .spec.js로 끝나는 파일이 실행 대상
  • eject: react-scripts eject는 CRA의 기본 설정을 해제하여 Webpack 및 Babel 설정을 직접 커스터마이징할 수 있도록 함
    • 이 명령어는 한 번 실행하면 되돌릴 수 없으므로 주의가 필요

 

CRA vs Vite 차이점(참고)

특징 CRA Vite
초기 로딩 속도 다소 느림 매우 빠름
빌드 속도 다소 느림 빠름
프로젝트 구성 파일 index.html 파일이 /public에 위치 루트 폴더에 위치
개발 서버 속도 느림 빠름(HMR 속도가 우수)
Webpack설정
CRA가 내부적으로 관리 vite.config.js에서 쉽게 설정 가능
테스트 설정 setupTests.js 기본 포함 직접 설정 필요(Vite +  Vitest)
커스터마이징 웹팩 설정을 변경하려면 eject 필요 vite.config.js로 쉽게 수정 가능

 

 

개발 환경 vs 운영 환경

  • 우리가 프로젝트를 실행할 때 실제로는 코드 파일 자체를 실행하는 것이 아니라, WAS(웹 애플리케이션 서버)를 통해 파일을 제공하는 방식으로 애플리케이션이 작동
  • WAS는 사용자가 브라우저나 클라이언트 프로그램을 통해 요청을 보낼 수 있도록 특정 포트에서 대기하면서, 요청이 들어오면 해당 요청에 맞는 파일이나 응답을 제공
개발 환경 운영 환경
사용자 (브라우저)
   |
   | 1. 로컬 개발 서버에 URL 요청 (http://localhost:3000)
  ↓
개발 서버 (Webpack Dev Server 또는 Vite Dev Server)
   |
   | 2. 요청 수신 → 메모리 상에서 실시간 빌드하여 파일 제공
  ↓
   | 3. 메모리에서 빌드된 최신 파일 응답 전송
  ↓
사용자 (브라우저)
   |
   | 4. 파일 렌더링 (화면 표시)
   |
   | 코드 변경 시 개발 서버가 HMR로 변경된 파일을 즉시 브라우저에 반영
사용자 (브라우저)
   |
   | 1. URL 요청 (https://myapp.com)
  ↓
웹 서버 (Nginx, Apache)  :80포트
   |
   | 2. 요청 수신 → 디스크에서 정적 파일 (HTML, CSS, JS) 찾기
  ↓
   | 3. 파일 응답 전송 (디스크에서 읽은 파일)
  ↓
사용자 (브라우저)
   |
   | 4. 파일 렌더링 (화면 표시)

 

왜 npm run dev를 하면 편하게 실행할 수 있는데 운영 환경에서 다른 방식을 사용하나요?

배포 운영 서버에서 정적 파일을 제공하는 이유

  • 성능: 이미 빌드된 정적 파일을 제공하면 디스크 I/O가 최소화되어 빠르고 효율적
    • 운영 서버에서는 최적화된 정적 파일(HTML, CSS, JavaScript)을 디스크에 미리 빌드해 두고, 사용자가 요청할 때마다 디스크에서 직접 제공
    • 이 방식은 파일을 미리 압축하고, 코드 스플리팅, 난독화 등으로 최적화된 상태로 제공하기 때문에 처리 속도가 빠르고, 리소스 사용이 적음
    • 웹 서버(Nginx, Apache 등)는 정적 파일 제공에 최적화되어 있어, 많은 사용자가 동시에 요청해도 안정적으로 응답 가능
  • 메모리 효율성: 메모리를 많이 사용하지 않으므로 서버 자원을 효율적으로 사용 가능
    • 개발 서버는 실시간 빌드와 HMR 기능을 위해 메모리를 많이 사용하고, 파일을 매번 메모리에서 컴파일해야 하기 때문에 메모리 사용량이 높아짐
    • 운영 환경에서는 이미 빌드된 정적 파일을 디스크에서 빠르게 제공하므로, 메모리와 CPU 리소스 사용을 최소화
  • 안정성: 예측 가능한 응답을 제공하며, 개발 중에만 필요한 HMR 같은 불필요한 기능이 없음
    • 개발 서버는 HMR과 같은 개발 편의 기능을 위해 추가적인 설정과 작업이 많음. 이러한 기능은 개발 중에는 유용하지만, 운영 환경에서는 불필요하며 오히려 잠재적인 버그나 성능 문제를 유발 가능
    • 배포용 웹 서버는 단순히 정적 파일을 제공하는 데 최적화되어 있기 때문에, 안정적이고 예측 가능한 응답을 제공
  • 보안: SSL 설정, 방화벽, 보안 헤더 등 다양한 보안 설정이 가능
    • 개발 서버는 보안 기능이 거의 없거나 기본적인 수준의 보안만 제공. 예를 들어, 외부에서 접근을 막기 위한 설정이 별도로 필요하지 않으며, 배포 환경에 필요한 SSL이나 방화벽 같은 보안 설정이 부족
    • Nginx와 같은 운영용 웹 서버는 SSL 인증서 설정, HTTP 헤더 보안 설정 등으로 웹 애플리케이션을 외부 공격으로부터 보호
  • 캐싱과 CDN: 정적 파일을 캐싱하고 CDN을 통해 전 세계에 빠르게 전달 가능
    • 운영 환경에서는 정적 파일을 캐싱하고, 전 세계에 분산된 CDN(Content Delivery Network)을 통해 제공 가능

 

외부 WAS(예: Nginx, Apache)를 사용해야하는 이유?

리액트(React)는 빌드 후 생성된 파일 내부에 WAS(Web Application Server)가 포함되어 있지 않기 때문에, 실제 배포 시에는 외부 WAS(예: Nginx, Apache)를 사용해야함