🦄 Cukehater

CRA에서 Vite로 갈아탄 이유 (그리고 실제로 얼마나 빨라졌는지)

🦄 Cukehater

·

1시간 전

타입: 블로그 / 유형: 프로젝트


CRA에서 Vite로 갈아탄 이유 (그리고 실제로 얼마나 빨라졌는지)

TL;DR

  • CRA(Webpack) → Vite(ESM)로 마이그레이션 진행
  • 빌드 시간 75% 감소 (54초 → 13초)
  • 개발 서버 기동 97% 개선 (4.2초 → 0.17초)
  • CI/CD 전체 시간 70% 단축 (7분 32초 → 2분 14초)
  • pnpm + 캐시 전략으로 설치 시간 최대 85% 감소
  • Husky + ESLint + Prettier로 코드 품질 자동화 체계 구축

1. 왜 CRA를 버렸는가

기존 프로젝트는 CRA + npm 기반이었습니다.

문제는 명확했습니다.

  • 개발 서버를 켤 때마다 4초 이상 기다려야 했고
  • 코드 조금만 건드려도 HMR이 느리거나 풀 리로드가 발생
  • 빌드도 매번 1분 가까이 소요
  • 무엇보다 CRA는 이미 Deprecated 상태

“이걸 계속 유지하는 게 맞나?”라는 고민이 시작이었습니다.

CRA는 Webpack + Babel 기반으로
👉 모든 걸 미리 번들링하는 구조

그래서 프로젝트가 커질수록:

  • 초기 기동 느려지고
  • 변경 반영 느려지고
  • 빌드도 같이 느려집니다

2. 왜 Vite를 선택했나

여기서 선택지는 여러 개였습니다.

  • Next.js
  • Vite
  • 기타 번들러들

저는 Vite를 선택했습니다.

이유는 명확했습니다:

1) SPA 유지하면서 성능 개선 가능

  • Next.js는 구조 자체가 바뀜 (SSR, routing 등)
  • Vite는 기존 구조 유지하면서 교체 가능

2) ESM 기반 개발 서버

Webpack과 가장 큰 차이:

  • CRA → “전부 번들링 후 실행”
  • Vite → “필요한 파일만 브라우저가 가져감”

즉,

👉 브라우저가 번들러 역할을 일부 수행합니다

그래서 결과적으로:

  • 서버 시작이 거의 즉시
  • HMR도 훨씬 빠름

3) esbuild + Rollup 구조

Vite는 이렇게 동작합니다:

  • 개발: esbuild (Go 기반, 초고속)
  • 배포: Rollup (최적화된 번들링)

이 조합이 생각보다 강력합니다.


3. pnpm까지 같이 도입한 이유

빌드 도구만 바꾸기엔 아쉬웠습니다.

npm도 같이 문제가 있었거든요.

  • node_modules 용량 과다
  • 설치 속도 느림
  • 유령 의존성 문제

그래서 같이 pnpm으로 전환했습니다.

pnpm 핵심 특징

  • 글로벌 스토어 + 하드링크
  • 의존성 엄격 관리 (phantom dependency 차단)
  • 병렬 설치

👉 결과적으로

  • 설치 속도 빨라지고
  • 디스크 낭비 줄고
  • 안정성 올라갑니다

4. 마이그레이션하면서 같이 한 것들

이 프로젝트는 단순히 번들러만 바꾼 게 아니라
👉 프론트엔드 개발 환경 전체를 재정의한 작업이었습니다.

1) 빌드/배포 구조 재설계

  • build → dist 구조 변경
  • buildspec.yml 수정
  • S3 업로드 경로 정리
  • 브랜치별 빌드 전략 재정립

2) 환경 변수 체계 변경

diff Copy
- process.env.REACT_APP_API
+ import.meta.env.VITE_API

이거 은근 많이 터집니다 😅


3) alias 정리

js Copy
import Header from 'components/Header'

상대경로 지옥 탈출


4) 코드 품질 자동화

이건 개인적으로 가장 만족한 부분입니다.

  • Husky
  • lint-staged
  • ESLint (flat config)
  • Prettier

👉 커밋 단계에서 자동으로:

  • lint 검사
  • 포맷팅
  • commit message 검증

“사람이 안 지켜도 시스템이 지키게 만든다”는 느낌


5. 성능 비교 (실측 결과)

🚀 빌드 성능

항목 CRA Vite
프로덕션 빌드 54초 13초
개발 서버 기동 4.2초 0.17초

👉 체감: 다른 프로젝트 같음


📦 번들 품질

항목 CRA Vite
JS 크기 8MB 6.4MB
CSS 크기 4MB 3.1MB

👉 vendor 분리(manualChunks) 효과 꽤 큼


⚙️ CI/CD 성능 (CodeBuild)

항목 CRA Vite
설치 21초 3초
빌드 2분 8초 41초
전체 7분 32초 2분 14초

👉 70% 단축

이건 진짜 체감됩니다.


6. 마이그레이션하면서 겪은 문제

이게 제일 중요한 파트입니다.

1) pnpm에서 터진 의존성 문제

npm에서는 돌아가던 코드가
pnpm에서는 깨졌습니다.

이유:

👉 숨겨진 의존성 (phantom dependency)

해결:

  • package.json에 명시 안 된 라이브러리 전부 추가
  • 의존성 구조 정리

2) 환경 변수 이슈

  • REACT_APP_VITE_ 변경 누락
  • process.envimport.meta.env

👉 이거 놓치면 런타임에서 터집니다


3) CI 캐시 문제

pnpm 캐시가 안 먹으면
npm보다 느려지는 경우도 있습니다.

👉 해결:

  • cache key 전략 수정
  • lock file 기준 캐싱

7. 결과 (단순 성능 이상)

이 작업을 하고 나서 느낀 건:

1) 개발 흐름이 안 끊긴다

  • 서버 바로 켜짐
  • 수정하면 즉시 반영

2) 배포 부담이 줄었다

  • 7분 → 2분

👉 배포 버튼 누르는 심리적 장벽이 낮아짐


3) “레거시 탈출” 효과

  • deprecated 경고 사라짐
  • 최신 React 대응 가능

8. 회고

처음엔 단순히

“Vite 빠르다던데 바꿔볼까?”

였는데

결과적으로는

👉 프론트엔드 개발 환경 전체를 다시 설계한 작업이었습니다.

특히 느낀 점:

  • 빌드 도구는 단순한 도구가 아니라
    👉 개발 경험 + 팀 생산성에 직접 영향
  • pnpm은 “선택”이 아니라
    👉 이제 거의 필수에 가까움

마무리

혹시 아직 CRA 쓰고 있다면,

👉 “지금 당장 바꾸세요”까지는 아니지만
👉 “언젠가는 반드시 바꿔야 할 작업”입니다.


다음 글에서는
👉 “Vite 도입할 때 꼭 터지는 문제들” 정리해보겠습니다.


수정이 필요한 부분이 있나요?

cukehater

🦄 Cukehater

개발 경험과 기술적 인사이트를 공유합니다 💻✨