CS/기타

Webpack에서 Vite로: CRA 마이그레이션 시 발생하는 문제와 해결 전략

Joonfluence 2026. 3. 22.

1. 문서 제목

  • Webpack에서 Vite로: CRA 마이그레이션 시 발생하는 문제와 해결 전략

2. 기술 개요 요약

CRA(Create React App)에서 Vite로의 마이그레이션은 단순한 빌드 도구 교체가 아니라, Webpack 기반 번들링 중심 아키텍처에서 ESM 기반 온디맨드 변환 구조로의 전환이다. Vite는 개발 환경에서 번들링을 제거하고 브라우저의 Native ES Module을 활용하며, production 빌드에서는 Rollup을 사용하여 최적화된 결과물을 생성한다. 이로 인해 빌드 속도와 개발 경험은 크게 개선되지만, TypeScript 처리 방식, HTML 엔트리 구조, 환경 변수 접근 방식 등에서 근본적인 차이가 발생한다.


3. 핵심 개념 정리

3.1 번들링 아키텍처 비교

항목 CRA (Webpack) Vite
Dev 서버 전체 번들링 ESM 기반 온디맨드 변환
HMR 느림 (전체 그래프 재계산) 매우 빠름 (파일 단위)
Production 빌드 Webpack Rollup
TS 변환 Babel esbuild

3.2 TypeScript 처리 방식

항목 CRA Vite
변환 Babel esbuild
타입 체크 포함 포함되지 않음
빌드 실패 조건 타입 에러 시 실패 타입 에러 있어도 빌드 가능

권장 설정

{
  "scripts": {
    "build": "tsc --noEmit && vite build"
  }
}

3.3 HTML 엔트리포인트 역할

항목 CRA Vite
위치 public/index.html 프로젝트 루트
역할 템플릿 엔트리포인트
script 주입 자동 수동
<script type="module" src="/src/main.tsx"></script>

3.4 환경 변수 시스템

항목 CRA Vite
Prefix REACT_APP_ VITE_
접근 방식 process.env import.meta.env
타입 지원 없음 있음
const apiUrl = import.meta.env.VITE_API_URL;

3.5 프록시 설정 방식

CRA

// setupProxy.js

Vite

export default defineConfig({
  server: {
    proxy: {
      "/api": {
        target: "http://localhost:4000",
      },
    },
  },
});

3.6 tsconfig 전략

구성 구조

tsconfig.json            → 서버
client/tsconfig.json     → 클라이언트
client/tsconfig.node.json → Vite 설정용

핵심 차이

환경 module moduleResolution
Node NodeNext NodeNext
Vite ESNext bundler

3.7 JSX Transform 변화

방식 특징
Classic React import 필요
Automatic React import 불필요
{
  "jsx": "react-jsx"
}

3.8 Dependency 충돌 이슈

문제

react-redux@7 → React 18 미지원

해결

react-redux → ^8.x 업그레이드

3.9 제거 가능한 의존성

  • react-scripts
  • http-proxy-middleware
  • web-vitals
  • redux-devtools-extension
  • @testing-library/* (미사용 시)

3.10 파일 구조 변화

Before (CRA)

  • public/index.html
  • src/index.tsx
  • setupProxy.js

After (Vite)

  • index.html (root)
  • src/main.tsx
  • vite.config.ts
  • tsconfig.node.json

4. 사용 예시 및 코드 스니펫

Vite 기본 설정

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";

export default defineConfig({
  plugins: [react()],
});

TypeScript 타입 확장

/// <reference types="vite/client" />

interface ImportMetaEnv {
  readonly VITE_API_URL: string;
}

5. 실제 사용 시 주의점 / Best Practice

1. 타입 체크는 반드시 별도로 수행

  • tsc --noEmit 필수
  • CI 파이프라인에 포함 권장

2. tsc -b 사용 시 제약 이해

  • composite: true 필요
  • noEmit과 충돌

3. index.html을 "코드"로 취급할 것

  • 더 이상 템플릿이 아님
  • 엔트리 포인트

4. CRA의 숨겨진 설정 제거 영향 고려

  • peer dependency 문제 노출됨
  • ESLint / Babel 설정 직접 관리 필요

5. moduleResolution: bundler 적극 활용

  • Vite 환경에서는 필수에 가까움

6. 참고자료 / 공식 문서


정리

CRA → Vite 전환의 본질은 다음 한 줄로 요약된다:

“보이지 않던 빌드 시스템을 직접 제어하는 구조로 이동하는 것”

이 변화는 단순히 속도 개선을 넘어서,
프론트엔드 빌드 시스템을 이해하는 깊이를 한 단계 끌어올린다.

반응형

댓글