Vite의 esbuild + Rollup 이중 구조 — 개발과 빌드가 다른 이유
Vite가 dev에는 esbuild, build에는 Rollup을 쓰는 이유. 같은 코드가 두 단계에서 다르게 동작하는 흔한 케이스와 디버깅 팁.
Vite는 개발 서버에서는 esbuild, 프로덕션 빌드는 Rollup을 사용합니다. 같은 도구를 쓰지 않는 이유는 두 단계가 요구하는 게 다르기 때문입니다. 이 차이를 이해하면 "개발에선 잘 되는데 빌드하면 깨지는" 흔한 문제를 빠르게 진단할 수 있습니다.
1. 두 도구의 역할 분리
| 단계 | 도구 | 역할 |
|---|---|---|
| 개발 (dev) | esbuild | 의존성 사전 번들링, TS 트랜스파일 |
| 빌드 (build) | Rollup | 프로덕션 번들, tree-shaking, 청크 분할 |
esbuild는 속도가 강점이지만 출력 최적화는 부족하고, Rollup은 출력 품질이 좋지만 느립니다. Vite는 두 도구의 강점만 결합합니다.
2. dev에서 esbuild가 하는 일
dev 서버는 ES Modules를 브라우저가 직접 받게 합니다. 단, node_modules 안의 CommonJS는 ESM으로 변환이 필요합니다. 이걸 esbuild가 처음 한 번만 합니다.
node_modules/react → esbuild가 ESM 묶음으로 변환 → .vite/deps/react.js
이후 브라우저는 .vite/deps/react.js를 직접 가져갑니다. 매 수정마다 전체 재번들이 일어나지 않아 dev 서버가 빠릅니다.
3. build에서 Rollup이 하는 일
프로덕션 빌드는 단일 번들이 아니라 여러 청크로 나뉩니다.
- 코드 스플리팅 (
import('./Modal')) - vendor 청크 분리 (
react,react-dom묶음) - tree-shaking (사용 안 한 export 제거)
- CSS 추출 + 청크별 분리
esbuild는 일부 기능(특히 advanced tree-shaking)이 약해, Vite는 빌드를 Rollup에 맡깁니다.
4. dev/build 결과가 다를 수 있는 이유
같은 코드여도 dev와 build에서 결과가 다른 경우가 있습니다.
- CommonJS interop 차이. esbuild와 Rollup의 default export 해석이 미세하게 다릅니다.
대부분 라이브러리는 둘 다 처리되지만, 오래된 패키지는 둘 중 하나만 동작합니다.1import dayjs from 'dayjs'; 2// dev에서는 dayjs() 동작, build에서는 dayjs.default 가 필요할 수 있음 - side-effect. package.json의
sideEffects: false를 Rollup이 더 엄격히 해석합니다. dev에서 동작했던 polyfill이 build에서 누락될 수 있습니다. - 환경변수.
import.meta.env는 dev에선 dynamic, build에선 static replace. dev에서는 동작하지만 build에서 undefined가 되는 케이스.
5. 디버깅 팁
빌드 결과가 이상하면 다음을 점검합니다.
1# 빌드만 실행 2pnpm build 3 4# 빌드 결과를 dev처럼 띄우기 5pnpm preview
vite preview로 빌드 결과를 직접 확인하는 습관을 들이면 dev/build 차이로 인한 문제를 일찍 발견합니다.
6. 의존성 사전 번들링 강제
dev 서버가 가끔 의존성을 다시 번들링하지 않을 때:
1# 캐시 무효화 2pnpm dev --force 3# 또는 .vite 디렉토리 삭제 4rm -rf node_modules/.vite
특히 의존성을 업데이트한 후 dev 서버가 깨지면 거의 이 케이스입니다.
7. 정리
| 단계 | 핵심 |
|---|---|
| dev | esbuild + 브라우저 ESM, 빠름, 사전 번들링 |
| build | Rollup, tree-shaking + 청크 분할 |
Vite의 빠른 개발 경험은 esbuild가, 작은 프로덕션 번들은 Rollup이 만듭니다. 두 단계의 차이를 알면 "왜 dev에서만 동작하지?" 같은 문제를 빠르게 좁힐 수 있습니다.
참고: Vite 공식 문서 — Why Vite / Dependency Pre-bundling.