Vite 완전 가이드 | Webpack보다 100배 빠른 차세대 빌드 도구
이 글의 핵심
Webpack을 대체하는 차세대 빌드 도구 Vite. ESBuild로 100배 빠른 개발 서버, 즉각적인 HMR, Rollup 기반 최적화된 프로덕션 빌드를 제공합니다. React·Vue·Svelte 모두 지원합니다.
이 글의 핵심
Vite(프랑스어로 “빠르다”)는 Webpack보다 100배 빠른 차세대 빌드 도구입니다. ESBuild로 의존성을 사전 번들링하고, 네이티브 ESM으로 개발 서버를 즉시 시작하며, Rollup으로 최적화된 프로덕션 빌드를 생성합니다.
목차
Vite란?
Vite는 2020년 Vue.js 창시자 Evan You가 개발한 프론트엔드 빌드 도구입니다.
🚀 핵심 특징
1. 즉각적인 서버 시작
Webpack:
- 전체 앱 번들링: 30-60초
- 모든 파일 처리 후 시작
Vite:
- 번들링 없음: 0.5초
- ESM으로 즉시 시작
→ 100배 빠름
2. 번개같은 HMR (Hot Module Replacement)
// 파일 수정 시
Webpack: 1-5초 (전체 재번들링)
Vite: 10-50ms (변경된 모듈만)
3. ESBuild 사전 번들링
- Go 언어로 작성된 초고속 번들러
- JavaScript 번들러보다 10-100배 빠름
- 의존성 자동 최적화
4. Rollup 프로덕션 빌드
- Tree Shaking
- Code Splitting
- CSS Code Splitting
- 최적화된 청크 생성
핵심 아키텍처: ESM, esbuild, Rollup
Vite는 “한 덩어리 번들”로 개발 서버를 띄우지 않습니다. 개발(Dev)과 프로덕션(Build)이 서로 다른 도구에 최적화된 역할로 나뉘어 있으며, 이것이 체감 성능의 근원입니다.
개발: 네이티브 ESM + 의존성 사전 번들(Pre-bundling)
애플리케이션 소스는 브라우저가 import로 직접 가져가도록 ESM(ES Modules) 흐름을 유지합니다. 반면 node_modules 안에는 ESM·CJS가 뒤섞이고, CommonJS→ESM 변환이나 다중 엔트리가 필요한 패키지가 섞여 있습니다. 그래서 Vite는 esbuild로 이러한 의존성 그래프만 미리 한 번 묶고, 그 결과를 .vite 캐시에 넣어 재시작·재설치가 아닌 이상 빠르게 재사용합니다. esbuild는 Go로 구현되어 있어 전형적인 JavaScript 기반 워커/단일 스레드 병목에서 자유로운 편이며, 트랜스폼(예: TypeScript의 타입 제거, JSX)도 매우 공격적으로 빠릅니다(단, Babel 풀 파이프라인을 그대로 쓰는 경우는 예외이므로 “항상 100배”로 단정하긴 어렵습니다).
프로덕션: Rollup이 “최종 공장”
vite build는 내부에서 Rollup을 올립니다. 트리 셰이킹, 동적/정적 import에 따른 청크 경계, CSS 추출, 에셋 파일명에 콘텐츠 해시 부여, manualChunks 등 번들 품질에 관한 결정이 대부분 Rollup 계층에서 내려갑니다. React·Vue·Svelte용 공식 플러그인은 개발·빌드 모두에서 변환·HMR·전처리 훅을 공유하므로, “로컬에서만 잘 돌고 배포는 깨지는” 류의 불일치를 줄이는 데 유리합니다.
Webpack과의 성능 비교(벤치마크 해석)
동일 머신·동일 Node 버전·최대한 비슷한 loader 의존성을 맞췄을 때, 중형 SPA에서 흔히 보고되는 경향은 다음과 같습니다(절대값은 프로젝트·의존성·디스크에 따라 달라지므로, 팀 내부 측정이 정답입니다).
| 측정 항목 | Webpack 5(일반적 설정) | Vite(기본) | 비고 |
|---|---|---|---|
dev 콜드 스타트 | 수십 초~수분대도 가능 | 보통 1~3초 대 | Vite는 “전체 앱 1덩어리”를 만들지 않음 |
| HMR(단일 TSX/Vue SFC 저장) | 0.5~수 초 | 수십 ms~수백 ms | 변경 모듈만 갱신 |
프로덕션 build | 설정·로더 누적에 민감 | esbuild minify+Rollup으로 경쟁력 | 대규모는 Rollup·플러그인 쪽 튜닝이 관건 |
권장 측정 절차: time npm run dev로 첫 화면까지, time npm run build로 CI·로컬 각각, 그리고 HMR은 DevTools Network 탭이 아니라 Vite·프레임워크 로그를 함께 보며 “저장~화면 반영” 구간을 기록하십시오. “100배” 같은 표현은 구조적 차이(전체번들 vs ESM+사전번들)의 비유이지, 모든 지표에 동일 비율이 보장되지는 않습니다.
Vite 시작하기
1️⃣ 프로젝트 생성
# React 프로젝트
npm create vite@latest my-react-app -- --template react
cd my-react-app
npm install
npm run dev
# Vue 프로젝트
npm create vite@latest my-vue-app -- --template vue
# Svelte 프로젝트
npm create vite@latest my-svelte-app -- --template svelte
# TypeScript 포함
npm create vite@latest my-app -- --template react-ts
2️⃣ 프로젝트 구조
my-app/
├── public/
│ └── vite.svg
├── src/
│ ├── App.tsx
│ ├── main.tsx
│ └── index.css
├── index.html # 진입점 (중요!)
├── package.json
├── vite.config.ts # Vite 설정
└── tsconfig.json
3️⃣ 개발 서버 실행
# 개발 서버 (http://localhost:5173)
npm run dev
# 프로덕션 빌드
npm run build
# 프로덕션 미리보기
npm run preview
Vite 설정
기본 설정 (vite.config.ts)
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [react()],
// 개발 서버 설정
server: {
port: 3000,
open: true, // 자동으로 브라우저 열기
cors: true,
},
// 빌드 설정
build: {
outDir: 'dist',
sourcemap: true,
minify: 'esbuild',
// 청크 크기 경고 제한
chunkSizeWarningLimit: 1000,
// Rollup 옵션
rollupOptions: {
output: {
manualChunks: {
vendor: ['react', 'react-dom'],
},
},
},
},
// 경로 별칭
resolve: {
alias: {
'@': '/src',
'@components': '/src/components',
'@utils': '/src/utils',
},
},
});
환경 변수
# .env
VITE_API_URL=https://api.example.com
VITE_APP_TITLE=My App
// src/config.ts
export const API_URL = import.meta.env.VITE_API_URL;
export const APP_TITLE = import.meta.env.VITE_APP_TITLE;
// 타입 안전성
interface ImportMetaEnv {
readonly VITE_API_URL: string;
readonly VITE_APP_TITLE: string;
}
interface ImportMeta {
readonly env: ImportMetaEnv;
}
환경 변수·모드(mode) 관리 심화
Vite는 클라이언트에 노출할 값만 VITE_ 접두사로 통일합니다. VITE_가 없는 키는 import.meta.env에 실리지 않으므로, API 키·시크릿을 실수로 프런트에 싣는 실수를 줄이는 설계입니다.
파일 우선순위(같은 키일 때 나중 것이 이김):
.env → .env.local(gitignore 권장) → .env.[mode] → .env.[mode].local
예: npm run build -- --mode staging이면 import.meta.env.MODE === 'staging'이고, .env.staging이 병합됩니다.
# .env.development
VITE_API_URL=http://localhost:8080
# .env.production
VITE_API_URL=https://api.example.com
// 실행 시 모드에 따라 다른 BASE
export const isDev = import.meta.env.DEV;
export const isProd = import.meta.env.PROD;
export const mode = import.meta.env.MODE; // "development" | "production" | 커스텀
서버 전용 값은 vite.config.ts에서 loadEnv로 읽고 define으로 주입하거나, 프록시·백엔드에만 두는 편이 안전합니다.
// vite.config.ts — CI·로컬에서만 쓰는 토큰을 서버 옵션에만 사용
import { defineConfig, loadEnv } from 'vite';
export default defineConfig(({ mode }) => {
const env = loadEnv(mode, process.cwd(), '');
return {
server: {
proxy: {
'/api': {
target: env.VITE_PROXY_TARGET ?? 'http://localhost:3001',
changeOrigin: true,
},
},
},
};
});
React + Vite 프로젝트
최적화된 React 설정
// vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import { visualizer } from 'rollup-plugin-visualizer';
export default defineConfig({
plugins: [
react({
// Fast Refresh 최적화
fastRefresh: true,
// Babel 플러그인
babel: {
plugins: [
['@babel/plugin-proposal-decorators', { legacy: true }],
],
},
}),
// 번들 크기 시각화
visualizer({
open: true,
gzipSize: true,
}),
],
build: {
rollupOptions: {
output: {
manualChunks: {
'react-vendor': ['react', 'react-dom', 'react-router-dom'],
'ui-vendor': ['@mui/material', '@emotion/react'],
},
},
},
},
});
Lazy Loading 예제
// src/App.tsx
import { lazy, Suspense } from 'react';
import { BrowserRouter, Routes, Route } from 'react-router-dom';
// 코드 스플리팅
const Home = lazy(() => import('./pages/Home'));
const About = lazy(() => import('./pages/About'));
const Dashboard = lazy(() => import('./pages/Dashboard'));
function App() {
return (
<BrowserRouter>
<Suspense fallback={<div>Loading...</div>}>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/dashboard" element={<Dashboard />} />
</Routes>
</Suspense>
</BrowserRouter>
);
}
export default App;
Vue + Vite 프로젝트
Vue 3 설정
// vite.config.ts
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import AutoImport from 'unplugin-auto-import/vite';
import Components from 'unplugin-vue-components/vite';
export default defineConfig({
plugins: [
vue(),
// 자동 import
AutoImport({
imports: ['vue', 'vue-router', 'pinia'],
dts: 'src/auto-imports.d.ts',
}),
// 컴포넌트 자동 등록
Components({
dts: 'src/components.d.ts',
}),
],
});
Vue 컴포넌트
<!-- src/components/Counter.vue -->
<script setup lang="ts">
import { ref, computed } from 'vue';
const count = ref(0);
const doubled = computed(() => count.value * 2);
const increment = () => {
count.value++;
};
</script>
<template>
<div>
<p>Count: {{ count }}</p>
<p>Doubled: {{ doubled }}</p>
<button @click="increment">Increment</button>
</div>
</template>
<style scoped>
button {
padding: 0.5rem 1rem;
font-size: 1rem;
}
</style>
플러그인 생태계
인기 플러그인
// vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import { VitePWA } from 'vite-plugin-pwa';
import compression from 'vite-plugin-compression';
import svgr from 'vite-plugin-svgr';
export default defineConfig({
plugins: [
react(),
// PWA 지원
VitePWA({
registerType: 'autoUpdate',
manifest: {
name: 'My App',
short_name: 'App',
theme_color: '#ffffff',
},
}),
// Gzip 압축
compression({
algorithm: 'gzip',
ext: '.gz',
}),
// SVG를 React 컴포넌트로
svgr(),
],
});
플러그인 시스템 심화: plugin·config·Rollup 훅
Vite 플러그인은 Rollup 호환 Plugin 인터페이스를 확장합니다. name은 필수이며, apply: 'build' | 'serve'로 개발/빌드 한쪽만 켤 수 있습니다. 자주 쓰는 훅은 config(최종 설정 병합), configResolved, resolveId·load(가상 모듈), transform(코드·JSX), buildStart·buildEnd 등입니다. 배열 앞쪽 플러그인이 먼저 관여하는 경우가 많으므로, React/Vue 프리앰블 플러그인은 맨 앞에 두는 것이 일반적입니다.
// plugins/html-banner.ts — 예: 빌드 시 HTML에 환경 배너 삽입(개념 예시)
import type { Plugin } from 'vite';
export function htmlBannerPlugin(): Plugin {
return {
name: 'html-banner',
apply: 'build',
transformIndexHtml(html) {
return html.replace(
'<body>',
`<body>\n <!-- build: ${new Date().toISOString()} -->`,
);
},
};
}
팁: 복잡한 조건 분기·대용량 JSON을 런타임에 읽을 때는 load+?raw·가상 모듈 패턴을 쓰면, 번들에 불필요한 코드가 스며드는 것을 막을 수 있습니다. 공식 플러그인 API와 Rollup 플러그인 개발을 함께 보시면, “왜 Vite가 이 훅을 노출하는지”가 이어집니다.
CSS 처리
1. CSS Modules
// Button.module.css
.button {
padding: 0.5rem 1rem;
background: blue;
color: white;
}
.button:hover {
background: darkblue;
}
// Button.tsx
import styles from './Button.module.css';
export const Button = () => {
return <button className={styles.button}>Click</button>;
};
2. PostCSS
// postcss.config.js
export default {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};
Tailwind CSS + Vite(실전)
Tailwind v4는 설정 방식이 달라질 수 있으니 공식 문서를 우선하되, v3 기준 전형적인 조합은 아래와 같습니다. content에 컴포넌트·페이지 경로를 빠짐없이 넣지 않으면, 프로덕션 CSS가 비정상적으로 작아집니다(가장 흔한 이슈).
// tailwind.config.js
/** @type {import('tailwindcss').Config} */
export default {
content: ['./index.html', './src/**/*.{js,ts,jsx,tsx,vue}'],
theme: { extend: {} },
plugins: [],
};
/* src/index.css */
@tailwind base;
@tailwind components;
@tailwind utilities;
Vite 쪽에서는 postcss.config.js만 있으면 main.tsx의 import './index.css'가 개발·빌드 모두에서 PostCSS를 탑니다. CSS 모듈과 글로벌 CSS를 섞을 때는 *.module.css만 모듈로 취급되고, 토큰(:root 변수)은 글로벌 엔트리에 두는 구성이 유지보수에 유리합니다.
3. Sass/Less
# Sass 설치
npm install -D sass
# Less 설치
npm install -D less
// styles.scss
$primary-color: #3498db;
.button {
background: $primary-color;
&:hover {
background: darken($primary-color, 10%);
}
}
성능 최적화
1. 의존성 사전 번들링
// vite.config.ts
export default defineConfig({
optimizeDeps: {
// 사전 번들링할 의존성
include: ['react', 'react-dom', 'lodash-es'],
// 제외할 의존성
exclude: ['@vite/client'],
},
});
2. Code Splitting
// 동적 import
const Component = lazy(() => import('./Component'));
// 조건부 로딩
if (condition) {
import('./heavy-module').then((module) => {
module.initialize();
});
}
3. 빌드 최적화
export default defineConfig({
build: {
// 압축 알고리즘
minify: 'esbuild', // 'terser' or 'esbuild'
// 소스맵 생성
sourcemap: false,
// CSS 코드 스플리팅
cssCodeSplit: true,
// 청크 크기 제한
chunkSizeWarningLimit: 500,
rollupOptions: {
output: {
// 청크 파일명 패턴
chunkFileNames: 'js/[name]-[hash].js',
entryFileNames: 'js/[name]-[hash].js',
assetFileNames: '[ext]/[name]-[hash].[ext]',
},
},
},
});
4. 프로덕션 빌드 튜닝(추가 옵션)
build.target:package.json의browserslist가 없을 때, 최소 브라우저 버전을 맞춥니다(너무 낮으면 폴리필·트랜스파일이 늘어납니다).build.reportCompressedSize:false로 두면 CI에서 gzip 크기를 매번 계산하지 않아 대형 프로젝트 빌드가 수 초~수십 초 줄어드는 사례가 있습니다.build.rollupOptions.output.assetFileNames/chunkFileNames: CDN 캐시·병렬 다운로드를 위해js/[name]-[hash].js처럼 일관되게.build.commonjsOptions: CommonJS-only 패키지를 ESM로 끌어올 때transformMixedEsModules등이 필요한 경우가 있습니다(이때는 공식 이슈·문서를 함께 확인).
// vite.config.ts — CI 시간 단축·자산 캐시 키 예시
export default defineConfig({
build: {
target: 'es2020',
reportCompressedSize: false,
chunkSizeWarningLimit: 800,
rollupOptions: {
output: {
manualChunks(id) {
if (id.includes('node_modules')) {
if (id.includes('react')) return 'react';
if (id.includes('lodash')) return 'vendor-lodash';
}
},
},
},
},
});
Vite vs Webpack
| 기능 | Vite | Webpack |
|---|---|---|
| 개발 서버 시작 | 0.5초 | 30-60초 |
| HMR | 10-50ms | 1-5초 |
| 번들러 | ESBuild | JavaScript |
| 의존성 처리 | 사전 번들링 | 전체 번들링 |
| 설정 | 간단 | 복잡 |
| 생태계 | 🌱 성장 중 | 🌳 성숙 |
| 프로덕션 빌드 | Rollup | Webpack |
위 표는 감이 안 잡힐 때 쓰는 한 장 요약이며, 측정은 앞의 “성능 비교(벤치마크 해석)” 절의 절차를 권장합니다. Webpack은 높은 자유도·풍부한 로더로 레거시·복잡한 엔트리에 강하고, Vite는 최신 ESM·간결한 기본 경험에 강합니다. 팀이 이미 Babel·커스텀 체인에 깊이 묶여 있다면, Vite로의 이전은 “설정을 단순화한다”가 아니라 “번들·변환 경계를 다시 짠다”에 가깝습니다.
실전 프로젝트: 대시보드 앱
프로젝트 설정
# 프로젝트 생성
npm create vite@latest dashboard -- --template react-ts
cd dashboard
npm install
# 의존성 추가
npm install react-router-dom @tanstack/react-query axios
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
Vite 설정
// vite.config.ts
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'),
},
},
server: {
port: 3000,
proxy: {
'/api': {
target: 'http://localhost:8000',
changeOrigin: true,
},
},
},
});
프로젝트 구조
src/
├── components/
│ ├── Layout.tsx
│ ├── Sidebar.tsx
│ └── Header.tsx
├── pages/
│ ├── Dashboard.tsx
│ ├── Users.tsx
│ └── Settings.tsx
├── hooks/
│ └── useAuth.ts
├── api/
│ └── client.ts
├── App.tsx
└── main.tsx
마이그레이션 가이드
CRA → Vite 전환
# 1. Vite 설치
npm install -D vite @vitejs/plugin-react
# 2. package.json 스크립트 변경
{
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
}
}
// 3. vite.config.ts 생성
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [react()],
});
<!-- 4. index.html 이동 (public/ → root) -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>My App</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
# 5. 불필요한 패키지 제거
npm uninstall react-scripts
SSR·SSG와 Vite: 프레임워크에 맡기는 것이 정석
Vite 자체는 vite 개발 서버·vite build로 SPA(싱글 페이지 앱)를 만드는 데 최적화되어 있습니다. SSR(서버 사이드 렌더링)·SSG(정적 생성)는 보통 프레임워크 레이어가 Vite에 플러그인을 꽂아 완성합니다. 예를 들어 Astro는 콘텐츠·아일랜드 아키텍처와 함께 SSG/SSR을, Nuxt 3·SvelteKit은 파일 기반 라우팅+SSR, Remix(/vite 플러그인)는 풀스택 라우팅을 각각 Vite와 통합합니다.
“순수 Vite만으로 SSR”을 직접 짜는 것은 가능하나(공식 SSR 가이드 참고), 프로덕션에서의 스트리밍·캐시·데이터 페칭·에러 경계를 모두 맡기엔 팀 생산성 대비 비용이 큽니다. 블로그·문서·마케팅 사이트는 Astro·SSG가, 로그인·권한·SEO가 중요한 앱은 프레임워크 SSR을 쓰는 구성이 일반적입니다. pkglog.com처럼 Astro SSG를 쓰는 경우, Vite는 “콘텐츠·컴포넌트·에셋 파이프라인”의 엔진이고, 배포·라우트는 Astro가 잡는 그림이 됩니다.
// ssr entry 개념 (프레임워크 없이 공식 가이드만 볼 때)
// server에 createServer·render를 두고, 클라이언트는 hydration 번들
// — 실무에서는 거의 Nuxt/Remix/Astro 쪽 구성을 씁니다.
Monorepo(pnpm·npm workspaces)에서 Vite
pnpm workspace, npm/yarn workspaces로 패키지를 쪼갰을 때, Vite는 루트의 vite.config가 보는 node_modules 해상도에 주의해야 합니다. 대표 이슈는 (1) 심볼릭 링크된 로컬 패키지가 HMR·사전번들(optimizeDeps)에서 누락되거나, (2) 라이브러리 패키지의 peerDependencies를 앱 쪽이 한 번에 못 풀어주는 경우입니다.
실전 팁
- 앱 패키지에만 Vite를 두고, 라이브러리 패키지는
tsup/unbuild로 ESM dist를 뽑거나, Vite 라이브러리 모드로 빌드해 소비 쪽이 안정적으로import하게 합니다. - 루트
tsconfig의paths와 Viteresolve.alias를 둘 다 맞춰야 IDE·번들·런타임이 어긋나지 않습니다. - 공유 UI 패키지를 소스로 직접 가리킬 땐
server.fs.allow에 모노레포 루트·패키지 경로를 열어 주어야 “파일이 밖에 있어 읽을 수 없다” 류의 오류를 피할 수 있습니다.
// apps/web/vite.config.ts
import { defineConfig } from 'vite';
import path from 'node:path';
export default defineConfig({
server: {
fs: {
allow: [
path.resolve(__dirname, '..'),
path.resolve(__dirname, '../../packages/ui'),
],
},
},
optimizeDeps: {
// 워크스페이스 패키지를 앱이 직접 소스로 import할 때
include: ['@my/ui', 'recharts'],
},
});
실제 마이그레이션에서 겪은 일(경험담)
필자는 CRA + react-scripts로 수년 운영되던 중규모 대시보드(React+TS+React Query)를 Vite로 옮긴 경험이 있습니다. 첫인상은 npm run dev가 눈에 띄게 짧아진 것이었고, HMR이 “잠시 멈췄다”가 아니라 수정이 즉시 반영되는 느낌이어서, 레이아웃·스타일 작업 흐름이 달라졌습니다. 반면 이전 작업에서 가장 오래 걸렸던 것은 (1) 환경 변수 이름을 REACT_APP_ → VITE_로 바꾸고, .env 로딩 순서를 팀 룰에 맞게 다시 쓰는 것, (2) 절대 경로·Jest가 react-scripts에 묶여 있었다면 Jest·Vitest·jsdom 설정을 처음부터 잡는 것, (3) 일부 CJS-only 패키지가 ESM·사전번들 단계에서 깨지지 않는지 확인하는 것이었습니다. 특히 Mock Service Worker·emotion·MUI 같이 Babel/전역 주입에 의존하던 스택은, Vite·플러그인 옵션을 한 번씩 훑어야 했습니다.
교훈: “설정이 줄어든다”는 말은 초기 템플릿에 가깝고, 레거시를 들고 오면 “줄 수 있는지”는 팀이 가진 커스텀·로더에 달려 있습니다. 그럼에도 개발·CI 피드백 루프가 짧아지는 이익이 커서, 필자는 새 greenfield·점진적 이전 모두 Vite(또는 Vite를 쓰는 메타 프레임워크)를 우선 고려하는 편입니다. 마이그레이션 체크리스트로는 index.html 루트 이동, import.meta.env로 통일, public 정적 경로 확인, 프록시/서버 origin, E2E의 base URL을 한 번에 점검하는 것을 권합니다.
핵심 정리
✅ Vite의 장점
- 압도적인 속도: Webpack보다 100배 빠른 개발 서버
- 즉각적인 HMR: 10-50ms 핫 리로드
- 간단한 설정: 최소한의 설정으로 시작
- 최적화된 빌드: Rollup 기반 프로덕션 번들
- 프레임워크 중립: React·Vue·Svelte 모두 지원
🚀 다음 단계
- Vite 공식 문서에서 심화 학습
- Awesome Vite에서 플러그인 탐색
- Vite Discord에서 커뮤니티 참여
시작하기:
npm create vite@latest로 5초 만에 프로젝트를 시작하고, Webpack보다 100배 빠른 개발 경험을 누리세요! 🚀