Skip to main content
Advertisement

환경 설정 — Vite + React 프로젝트 구성

Vite를 선택하는 이유

2021년 이전까지는 **Create React App(CRA)**이 공식 스캐폴딩 도구였습니다. 하지만 CRA는 내부적으로 Webpack을 사용하여 개발 서버 시작에 수십 초가 걸리는 문제가 있었습니다. 현재 React 공식 문서는 CRA 대신 Vite, Next.js, Remix 등을 권장합니다.

CRA vs Vite 비교

항목CRAVite
번들러Webpackesbuild(개발) + Rollup(빌드)
콜드 스타트20~60초1~3초
HMR 속도느림즉각 반응
유지보수사실상 중단됨활발히 개발 중
번들 크기더 큼더 작음

Vite + React 프로젝트 생성

기본 생성

npm create vite@latest my-react-app -- --template react
cd my-react-app
npm install
npm run dev

TypeScript 템플릿

npm create vite@latest my-react-app -- --template react-ts

인터랙티브 모드

npm create vite@latest
# 프롬프트에 따라 선택:
# ✔ Project name: my-app
# ✔ Select a framework: React
# ✔ Select a variant: JavaScript / TypeScript / JavaScript + SWC / TypeScript + SWC

**SWC(Speedy Web Compiler)**는 Rust로 작성된 초고속 Babel 대체재입니다. 성능이 중요하다면 react-swc 변형을 선택하세요.


프로젝트 폴더 구조

my-react-app/
├── public/ # 정적 파일 (그대로 복사됨)
│ └── vite.svg
├── src/ # 소스 코드
│ ├── assets/ # 이미지, 폰트 등
│ ├── components/ # 재사용 컴포넌트
│ ├── pages/ # 페이지 컴포넌트 (라우터 사용 시)
│ ├── hooks/ # 커스텀 훅
│ ├── App.jsx # 루트 컴포넌트
│ ├── App.css
│ ├── main.jsx # 진입점
│ └── index.css
├── index.html # Vite의 진입점 HTML
├── vite.config.js # Vite 설정
├── package.json
└── .eslintrc.cjs # ESLint 설정

main.jsx — 진입점

import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import './index.css';
import App from './App.jsx';

createRoot(document.getElementById('root')).render(
<StrictMode>
<App />
</StrictMode>,
);

App.jsx — 루트 컴포넌트

import { useState } from 'react';
import reactLogo from './assets/react.svg';
import './App.css';

function App() {
const [count, setCount] = useState(0);

return (
<div>
<h1>Vite + React</h1>
<button onClick={() => setCount(count + 1)}>
count is {count}
</button>
</div>
);
}

export default App;

개발 명령어

npm run dev      # 개발 서버 시작 (기본 포트: 5173)
npm run build # 프로덕션 빌드 (dist/ 폴더 생성)
npm run preview # 빌드 결과물을 로컬에서 미리보기
npm run lint # ESLint 실행

포트 변경

// vite.config.js
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

export default defineConfig({
plugins: [react()],
server: {
port: 3000, // 개발 서버 포트
open: true, // 브라우저 자동 열기
},
});

경로 별칭(Path Alias) 설정

// vite.config.js
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import path from 'path';

export default defineConfig({
plugins: [react()],
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),
'@components': path.resolve(__dirname, './src/components'),
'@hooks': path.resolve(__dirname, './src/hooks'),
},
},
});

이후 절대 경로로 import 가능합니다.

// 변경 전
import Button from '../../components/Button';

// 변경 후
import Button from '@components/Button';

ESLint + Prettier 설정

설치

npm install -D eslint-config-prettier prettier
npm install -D @typescript-eslint/parser @typescript-eslint/eslint-plugin # TypeScript 사용 시

.eslintrc.cjs

module.exports = {
root: true,
env: { browser: true, es2024: true },
extends: [
'eslint:recommended',
'plugin:react/recommended',
'plugin:react-hooks/recommended',
'prettier', // prettier와 충돌하는 규칙 비활성화
],
parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
plugins: ['react-refresh'],
rules: {
'react/react-in-jsx-scope': 'off', // React 17+ 자동 JSX Transform
'react-refresh/only-export-components': 'warn',
},
};

.prettierrc

{
"semi": true,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "es5",
"printWidth": 100
}

React DevTools 설치

브라우저 확장 프로그램으로 설치합니다.

주요 기능

용도
Components컴포넌트 트리 탐색, props/state 확인 및 수정
Profiler렌더링 성능 측정, 어느 컴포넌트가 왜 렌더링됐는지

DevTools 팁

// 컴포넌트에 displayName 설정 (익명 함수 시 유용)
const MemoizedCard = React.memo(function Card({ title }) {
return <div>{title}</div>;
});
MemoizedCard.displayName = 'MemoizedCard';

실전 예제: 추천 폴더 구조 (Feature-based)

src/
├── features/
│ ├── auth/
│ │ ├── components/ LoginForm.jsx, RegisterForm.jsx
│ │ ├── hooks/ useAuth.js
│ │ ├── api.js # auth 관련 API 호출
│ │ └── index.js # public API export
│ └── products/
│ ├── components/ ProductCard.jsx, ProductList.jsx
│ ├── hooks/ useProducts.js
│ └── index.js
├── shared/
│ ├── components/ Button.jsx, Modal.jsx, Input.jsx
│ ├── hooks/ useDebounce.js, useLocalStorage.js
│ └── utils/ formatDate.js, validators.js
├── App.jsx
└── main.jsx

고수 팁

1. Vite 환경 변수

# .env
VITE_API_URL=https://api.example.com
VITE_APP_TITLE=My App
// 컴포넌트에서 사용
const apiUrl = import.meta.env.VITE_API_URL;

VITE_ 접두사가 붙은 변수만 클라이언트에 노출됩니다.

2. HMR 유지를 위한 export 규칙

// ✅ 컴포넌트를 named export 또는 default export 하나만
export default function Counter() { /* ... */ }

// ❌ 컴포넌트와 다른 값을 같은 파일에서 export하면 HMR 경고 발생
export const CONSTANT = 42;
export default function Counter() { /* ... */ }

3. 빌드 최적화 확인

npm run build
# dist/ 폴더 내 파일 크기 확인
# index-[hash].js: 앱 코드
# vendor-[hash].js: node_modules 코드 (청크 분리됨)

vite-bundle-visualizer 패키지로 번들 구성을 시각적으로 분석할 수 있습니다.

Advertisement