React 프로젝트 생성 및 배포
React를 다루기 위해 기본적인 준비를 마쳤으니, 이제 본격적인 React 프로젝트를 생성해 보겠습니다. 아래의 내용을 확인하면서 따라와 주세요!
1. React 프로젝트 생성 및 실행
React 프로젝트를 시작하기 위해서는 먼저 개발 환경을 설정해야 합니다. 이를 위해 Vite라는 빌드 도구를 사용합니다. Vite는 빠른 개발 서버와 최적화된 빌드를 제공하는 차세대 프론트엔드 빌드 도구입니다. 기존의 Create React App(CRA)보다 훨씬 빠른 개발 환경을 제공하며, 현재 React 공식 문서에서도 권장하는 방식입니다.
1.1 프로젝트 생성
프로젝트를 시작할 디렉토리로 이동한 후, 터미널에서 다음 명령어를 실행하여 새로운 React 프로젝트를 생성할 수 있습니다.
npm create vite@latest my-app -- --template react
npm create란?
npm create는 npm init의 별칭으로, 프로젝트 생성 도구를 실행할 때 사용합니다. vite@latest는 최신 버전의 Vite를 사용한다는 의미이고, --template react는 React 템플릿을 사용하여 프로젝트를 생성한다는 의미입니다.
이 명령어를 사용하려면 Node.js 18.0.0 이상 버전이 필요합니다.
이 명령어는 'my-app'이라는 이름의 새 디렉토리를 만들고, 그 안에 React 프로젝트의 기본 구조와 필요한 파일들을 생성합니다. 'my-app' 대신 원하는 프로젝트 이름으로 변경할 수 있습니다. 예를 들어, 'react-todo-app'이라는 이름으로 프로젝트를 만들고 싶다면 아래와 같은 명령어를 실행하면 됩니다.
npm create vite@latest react-todo-app -- --template react
프로젝트 생성이 완료되면, 해당 디렉토리로 이동하여 의존성을 설치하고 개발을 시작할 수 있습니다.
혹시 에러가 났나요?
- Node.js 버전을 확인해주세요. Vite는 Node.js 18 이상이 필요합니다.
node -v
- npm 캐시 문제가 발생했다면 아래 명령어를 통해 캐시를 비워 주세요.
npm cache clean --force
1.2 프로젝트 실행
프로젝트를 생성한 후, 다음 명령어로 의존성을 설치하고 React 애플리케이션을 실행할 수 있습니다.
cd my-app # my-app 폴더로 이동
npm install # 의존성 설치
npm run dev # 개발 서버 실행
이 명령어는 개발 서버를 시작하고, 기본적으로 http://localhost:5173 에서 애플리케이션을 실행합니다. 브라우저에서 이 주소로 접속하면 Vite + React 로고와 함께 기본 페이지를 볼 수 있습니다.
다음과 같은 문구와 페이지가 나타났다면 성공입니다.

2. 프로젝트 구조
Vite로 생성한 React 프로젝트의 기본 구조는 다음과 같습니다.
- node_modules/: npm으로 설치한 외부 패키지들이 저장되는 폴더
- public/: 정적 파일을 저장하는 폴더 (빌드 시 그대로 복사됨)
- src/: 실제 개발 코드가 위치하는 폴더
- App.jsx: 메인 컴포넌트
- main.jsx: React 앱의 시작점
- index.html: 앱의 HTML 진입점
- vite.config.js: Vite 설정 파일
- package.json: 프로젝트 정보와 의존성 목록
React 앱이 실행될 때 파일들은 다음 순서로 호출됩니다.
학습 단계에서는 꼭 필요한 파일만 남기고 나머지는 제거하는 것이 좋습니다. 다음 단계에서는 주요 파일들을 살펴보겠습니다.
2.1 index.html
Vite에서 index.html은 프로젝트 루트에 위치하며 React 애플리케이션의 진입점입니다. 여기에 React 컴포넌트가 렌더링될 root 요소(<div id="root"></div>)가 포함됩니다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>React App</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
</body>
</html>
CRA(Create React App)와의 차이점
과거에는 아래와 같은 방식으로 React를 설치했습니다.
npx create-react-app my-app
이 방식을 CRA(Create React App)라고 부릅니다. CRA에서는 index.html이 public 폴더 안에 있었지만, Vite에서는 프로젝트 루트에 위치합니다. 또한 <script> 태그로 직접 진입점 파일을 연결하는 것이 특징입니다.
| 항목 | CRA | Vite |
|---|---|---|
| 빌드 속도 | 느림 (Webpack 기반) | 빠름 (ESBuild 기반) |
| 개발 서버 시작 | 느림 | 거의 즉시 |
| 공식 지원 | 유지보수 모드 | 활발한 개발 중 |
| React 공식 문서 | 더 이상 권장하지 않음 | 권장 |
2.2 App.jsx
이 파일은 애플리케이션의 메인 컴포넌트입니다. 여기서 애플리케이션의 기본 구조를 정의합니다.
이 파일을 열어보면 return()문 안에 HTML과 유사한 구문이 있는 것을 볼 수 있습니다. 이런 문법은 바로 JSX(JavaScript + XML)라고 합니다. JSX에 대한 내용은 다음 챕터에서 자세히 알아보도록 하고 용어만 기억하고 넘어갑시다.
파일의 내용은 다음 코드블럭과 같이 수정해주세요.
function App() {
return <div className="App"></div>;
}
export default App;
2.3 main.jsx
이 파일은 React 애플리케이션의 시작점입니다. App 컴포넌트를 가져와서 렌더링하는 역할을 합니다. CRA의 index.js와 같은 역할을 합니다.
파일의 내용은 다음 코드블럭과 같이 수정해주세요.
import ReactDOM from 'react-dom/client';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);
React 프로젝트를 생성하고 초기 설정을 하는 과정은 새 프로젝트를 시작할 때마다 반복되는 작업입니다. 이를 효율적으로 관리하기 위해 자주 사용하는 기본 구조의 프로젝트 템플릿을 만들어 GitHub으로 관리하는 방법을 추천드립니다.
파일들은 모두 제각각 분리되어 있는데 어떻게 합쳐지는건가요?
index.html, src 폴더의 App.jsx, main.jsx와 같은 파일들을 하나로 묶는 작업은 Vite의 번들러가 해줍니다. npm run build 명령어를 실행하면 추가하지 않았던 dist폴더를 확인할 수 있습니다. 이것이 바로 모듈 별로 분리되어 있던 JS파일을 하나로 묶은(번들링한) 결과물입니다.

2.4 Strict Mode
Vite로 생성한 프로젝트의 main.jsx를 처음 열어보면 다음과 같이 <StrictMode>로 감싸져 있습니다.
import { StrictMode } from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<StrictMode>
<App />
</StrictMode>,
);
Strict Mode는 React가 개발 중 실수로 발생할 수 있는 버그를 찾아내기 위해 컴포넌트를 두 번 실행하는 기능입니다. 이로 인해 console.log가 두 번 출력되거나, 특정 함수가 두 번 호출되는 현상이 발생할 수 있습니다.
이는 개발 환경에서만 동작하며, 실제 배포(프로덕션) 환경에서는 영향을 미치지 않습니다. 학습 단계에서는 혼란을 줄 수 있으므로 <StrictMode>를 제거하고 진행합니다.
import ReactDOM from 'react-dom/client';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);
3. 프로젝트 배포
GitHub Pages를 사용하여 React 애플리케이션을 무료로 호스팅할 수 있습니다.
3.1 GitHub repo 생성
GitHub 명령어, repo나 pages로 웹페이지를 생성하는 방법을 모른다면 아래 링크를 참고해주세요. 여기서는 React 프로젝트 배포에 집중하기 위해 GitHub에 대한 설명은 생략합니다.
알아서 잘 딱 깔끔하고 센스있게 정리하는 GitHub 핵심 개념우선 GitHub에 새로운 Repository를 생성합니다. Repository 이름은 여러분의 프로젝트 이름으로 설정합니다. 저는 testvite라는 이름으로 생성하였습니다. 설명을 편하게 하기 위해 README.md 파일은 생성했습니다.
이 파일을 로컬로 클론(clone)합니다. 아래 주소는 여러분의 Repository 주소로 변경해주세요.
git clone https://github.com/paullabkorea/testvite.git .
3.2 프로젝트 설정
이제 React 프로젝트를 만듭니다. 비어있지 않다는 옵션이 뜰텐데 무시하는 옵션을 선택하고 진행합니다. React와 JavaScript 템플릿을 선택합니다.
npm create vite@latest . -- --template react
vite.config.js파일에 base 경로를 설정합니다.
base는 배포될 때 사용되는 기본 경로를 지정합니다. GitHub Pages에서는 저장소 이름이 경로에 포함되므로, base 값에는 저장소 이름을 넣어야 합니다. 저의 경우 저장소 이름이 testvite입니다.
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [react()],
base: '/your-repo-name/',
});
- gh-pages 패키지를 설치합니다.
npm install gh-pages --save-dev
- package.json의 scripts 섹션에 다음을 추가합니다.
"scripts": {
"predeploy": "npm run build",
"deploy": "gh-pages -d dist",
...
}
CRA와의 차이점
CRA는 빌드 결과물이 build 폴더에 생성되지만, Vite는 dist 폴더에 생성됩니다. 따라서 deploy 명령어에서 -d dist를 사용합니다.
- 터미널에서 add, commit, push를 차례로 실행하여 수정된 코드를 Repository에 업로드합니다.
3.3 배포
- 아래 명령어를 실행해 애플리케이션을 빌드하고 배포합니다. 이 명령어를 사용하면
predeploy스크립트가 먼저 실행되어 프로젝트가 빌드되고, 그 다음에deploy스크립트가 실행되어 빌드된 파일이 GitHub Pages에 배포됩니다.
npm run deploy
- GitHub 저장소 설정에서 pages 탭으로 가보면 배포 브랜치가 gh-pages 브랜치로 변경되어 있습니다. 만약 변경이 되어 있지 않다면 수동으로 gh-pages 브랜치를 선택해줍니다.
몇 분 정도 기다리면 지정된 URL에서 프로젝트를 확인할 수 있습니다.
빈 페이지가 출력된다면?
GitHub Pages에서 React 프로젝트를 배포했을 때 빈 페이지가 나오는 문제는 주로 react-router-dom을 사용할 때 발생합니다. 이때, BrowserRouter에 basename을 추가한 후 다시 push와 deploy를 진행합니다.
<BrowserRouter basename={import.meta.env.BASE_URL}>
{/* 라우트 설정 */}
</BrowserRouter>
npx my-react-vite-app [프로젝트 이름]
앞으로는 실습환경 생성을 위해 아래의 명령어를 통해 프로젝트를 생성합니다. 여러분들의 실습을 위한 기본적인 환경을 vite와 동일하게 유지하면서 필요없는 파일은 제거하였습니다.
npx my-react-vite-app [프로젝트 이름]