Vite: Công Cụ Build Siêu Nhanh Cho Dự Án Web Hiện Đại
Khám phá Vite — công cụ build thế hệ mới siêu nhanh cho React, Vue, Svelte và Vanilla JS. Từ cài đặt, cấu hình đến triển khai production với HMR nhanh như chớp.
Bạn đã bao giờ ngồi chờ 30 giây để khởi động Webpack dev server? Hay chờ 5 giây mỗi lần sửa code và reload? Nếu bạn đang dùng Create React App, Webpack hay Parcel, có lẽ bạn đã quen với cảm giác này.
Nhưng mọi thứ đã thay đổi.
Vite (phát âm /vit/ — tiếng Pháp nghĩa là “nhanh”) là công cụ build thế hệ mới đang thay đổi cách chúng ta phát triển web. Với khởi động tức thì, HMR (Hot Module Replacement) nhanh như chớp, và cấu hình đơn giản, Vite đã trở thành tiêu chuẩn mới cho frontend tooling.
Trong bài viết này, chúng ta sẽ khám phá mọi khía cạnh của Vite — từ cài đặt cơ bản, cấu hình nâng cao, đến triển khai production — với nhiều ví dụ thực tế.
Vite là gì?
Vite là một build tool và dev server thế hệ mới, được tạo bởi Evan You (tác giả của Vue.js) vào năm 2020. Vite tận dụng native ES Modules (ESM) trên trình duyệt hiện đại để loại bỏ hoàn toàn công đoạn bundle trong development — đây là bước đột phá so với các công cụ truyền thống.
So sánh Vite vs Webpack
| Tính năng | Vite | Webpack / CRA |
|---|---|---|
| Khởi động dev server | < 1 giây (ESM native) | 20-60 giây (bundle toàn bộ) |
| HMR | Tức thì, giữ nguyên state | Chậm hơn, thường reload full page |
| Cấu hình | Đơn giản, ít boilerplate | Phức tạp, nhiều config |
| TypeScript | Built-in, zero config | Cần cấu hình thêm |
| CSS Modules | Built-in | Cần cấu hình |
| Production build | Rollup (nhanh, nhỏ) | Webpack (chậm hơn) |
| Plugin ecosystem | Rollup-compatible, đang phát triển | Lớn, nhiều plugin |
Tại sao Vite nhanh hơn?
Bí mật nằm ở cách Vite xử lý code trong development:
Webpack (cách cũ): Khi bạn chạy npm start, Webpack phải:
- Đọc toàn bộ source code
- Parse và phân tích dependency graph
- Bundle tất cả file thành một (hoặc vài) file
- Gửi bundle đến trình duyệt
Dự án càng lớn, thời gian càng lâu.
Vite (cách mới): Khi bạn chạy npm run dev, Vite:
- Chia code thành hai nhóm: dependencies (node_modules, bundle bằng esbuild) và source code (ESM native)
- Serve source code trực tiếp qua trình duyệt — mỗi file là một ES module riêng
- Trình duyệt tự tải các module khi cần
Kết quả: Khởi động dưới 1 giây, bất kể dự án lớn cỡ nào.
Cài đặt Vite
Yêu cầu
- Node.js phiên bản 18+ (khuyến nghị 20+)
- npm, yarn, pnpm hoặc bun
Tạo dự án mới
Cách nhanh nhất để bắt đầu với Vite:
npm create vite@latest
Chạy lệnh trên và bạn sẽ thấy menu tương tác:
✔ Project name: … my-app
✔ Select a framework: › React
✔ Select a variant: › TypeScript
Scaffolding project in /Users/you/my-app...
Done. Now run:
cd my-app
npm install
npm run dev
Bạn cũng có thể tạo dự án trực tiếp với template:
# React với JavaScript
npm create vite@latest my-app -- --template react
# React với TypeScript
npm create vite@latest my-app -- --template react-ts
# Vue
npm create vite@latest my-app -- --template vue
# Vue + TypeScript
npm create vite@latest my-app -- --template vue-ts
# Svelte
npm create vite@latest my-app -- --template svelte
# Svelte + TypeScript
npm create vite@latest my-app -- --template svelte-ts
# Vanilla JavaScript
npm create vite@latest my-app -- --template vanilla
# Vanilla TypeScript
npm create vite@latest my-app -- --template vanilla-ts
Templates có sẵn
Vite cung cấp các template chính thức:
vanilla/vanilla-ts— JavaScript/TypeScript thuầnvue/vue-ts— Vue 3react/react-ts— React 18+preact/preact-ts— Preactlit/lit-ts— Lit (Web Components)svelte/svelte-ts— Sveltesolid/solid-ts— SolidJSqwik/qwik-ts— Qwik
Cấu trúc dự án Vite
Sau khi tạo dự án React với Vite, bạn sẽ thấy cấu trúc:
my-app/
├── index.html
├── package.json
├── vite.config.js
├── tsconfig.json
├── public/
│ └── vite.svg
└── src/
├── main.jsx
├── App.jsx
├── App.css
└── assets/
└── react.svg
index.html — Entry point khác biệt
Điểm khác biệt lớn nhất: index.html nằm ở root, không phải trong public/. Vite coi index.html là entry point thực sự của ứng dụng:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<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.jsx"></script>
</body>
</html>
Chú ý type="module" — đây là cách Vite dùng native ESM.
vite.config.js — Trái tim cấu hình
File cấu hình chính của Vite, có thể viết bằng JS hoặc TS:
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
export default defineConfig({
plugins: [react()],
})
Các tính năng chính của Vite
1. Hot Module Replacement (HMR)
HMR là tính năng “thần thánh” nhất của Vite. Khi bạn sửa code, chỉ file vừa sửa được cập nhật — không reload toàn bộ trang, và state của component được giữ nguyên.
// App.jsx — thử sửa dòng này
function App() {
const [count, setCount] = useState(0)
return (
<div>
<h1>Vite + React</h1>
<p>Count: {count}</p>
{/* Sửa nội dung button — HMR cập nhật ngay, count vẫn giữ nguyên */}
<button onClick={() => setCount(c => c + 1)}>
Click me!
</button>
</div>
)
}
Với Vite HMR, bạn có thể sửa style, component, hoặc logic — mọi thay đổi xuất hiện trong dưới 50ms.
2. Native ES Modules
Vite không bundle source code trong development. Thay vào đó, nó serve source code nguyên bản dưới dạng ES modules:
// Bạn viết:
import { formatDate } from './utils/date'
import { Button } from './components/Button'
// Vite serve trực tiếp lên trình duyệt:
import { formatDate } from '/src/utils/date.js'
import { Button } from '/src/components/Button.jsx'
Trình duyệt hiện đại (Chrome, Firefox, Edge, Safari 15+) đều hỗ trợ type="module" — trình duyệt tự tải và cache các module.
3. TypeScript built-in
Vite hỗ trợ TypeScript không cần cấu hình. Chỉ cần import file .ts hoặc .tsx:
// utils/format.ts
export function formatPrice(price: number, currency: string): string {
return new Intl.NumberFormat('vi-VN', {
style: 'currency',
currency
}).format(price)
}
// App.tsx
import { formatPrice } from './utils/format'
function App() {
return <div>Price: {formatPrice(25000, 'VND')}</div>
}
Lưu ý: Vite chỉ transpile TypeScript, không kiểm tra type (type checking). Để type checking, cài
tsc --noEmithoặc dùng IDE.
4. CSS & Preprocessor
Vite hỗ trợ CSS modules, CSS preprocessor, và PostCSS:
/* App.module.css */
.container {
max-width: 1200px;
margin: 0 auto;
}
.title {
font-size: 2rem;
color: #646cff;
}
import styles from './App.module.css'
function App() {
return (
<div className={styles.container}>
<h1 className={styles.title}>Hello Vite!</h1>
</div>
)
}
Dùng Sass: Chỉ cần cài package và import .scss:
npm install -D sass
// styles/variables.scss
$primary: #646cff;
$padding: 16px;
// components/Card.scss
@use '../styles/variables' as *;
.card {
padding: $padding;
background: $primary;
color: white;
}
5. Static Assets
Import ảnh, font, JSON, và các file tĩnh trực tiếp:
import reactLogo from './assets/react.svg'
import data from './data.json'
function App() {
return (
<div>
<img src={reactLogo} alt="React" />
<p>{data.title}</p>
</div>
)
}
6. Environment Variables
Vite dùng import.meta.env thay vì process.env:
# .env
VITE_API_URL=https://api.example.com
VITE_APP_TITLE=My App
// Trong code
const apiUrl = import.meta.env.VITE_API_URL
const title = import.meta.env.VITE_APP_TITLE
Quan trọng: Chỉ biến có prefix
VITE_mới được expose ra client.
Cấu hình nâng cao
Aliases (Đường dẫn ngắn)
Thay vì ../../../components/Button, dùng 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'),
'@utils': path.resolve(__dirname, './src/utils'),
}
}
})
// Giờ bạn có thể viết:
import Button from '@components/Button'
import { formatDate } from '@utils/date'
Proxy API
Tránh CORS khi gọi API từ dev server:
// vite.config.js
export default defineConfig({
server: {
proxy: {
'/api': {
target: 'http://localhost:3000',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '')
}
}
}
})
Khi bạn gọi fetch('/api/users'), Vite sẽ proxy đến http://localhost:3000/users.
Global CSS / Reset CSS
Import global CSS trong main.jsx:
// main.jsx
import './styles/global.css'
import './styles/reset.css'
Multi-page App
Vite hỗ trợ multi-page app với cấu hình:
// vite.config.js
import { defineConfig } from 'vite'
import { resolve } from 'path'
export default defineConfig({
build: {
rollupOptions: {
input: {
main: resolve(__dirname, 'index.html'),
about: resolve(__dirname, 'about/index.html'),
blog: resolve(__dirname, 'blog/index.html'),
}
}
}
})
Production Build
Build cơ bản
npm run build
# hoặc
npx vite build
Kết quả trong thư mục dist/:
dist/
├── index.html
├── assets/
│ ├── index-abc123.js
│ ├── index-abc123.css
│ └── react-xyz789.js
Vite tự động:
- Code splitting — tách vendor (React, library) ra khỏi app code
- CSS minification — nén CSS
- Tree-shaking — loại bỏ code không dùng
- Asset hashing — thêm hash vào filename cho cache busting
Preview build
npm run preview
# Serve thư mục dist/ để kiểm tra trước khi deploy
Tối ưu build
// vite.config.js
export default defineConfig({
build: {
// Tắt sourcemap cho production
sourcemap: false,
// Chunk size warning (mặc định 500KB)
chunkSizeWarningLimit: 1000,
// Rollup options
rollupOptions: {
output: {
// Tách thủ công vendor chunks
manualChunks: {
vendor: ['react', 'react-dom'],
ui: ['antd', '@ant-design/icons'],
}
}
}
}
})
Deploy Vite Project
Deploy lên Vercel (Miễn phí)
- Kết nối GitHub repo với Vercel
- Vercel tự động nhận diện Vite và cấu hình:
- Build command:
npm run build - Output directory:
dist
- Build command:
- Deploy — xong!
Deploy lên Netlify
Thêm file netlify.toml:
[build]
command = "npm run build"
publish = "dist"
[[redirects]]
from = "/*"
to = "/index.html"
status = 200
Deploy lên GitHub Pages
Dùng plugin vite-plugin-gh-pages hoặc cấu hình:
// vite.config.js
export default defineConfig({
base: '/your-repo-name/', // Quan trọng!
plugins: [react()],
})
Vite Plugin Ecosystem
Plugin phổ biến
# React
npm install -D @vitejs/plugin-react
# Vue
npm install -D @vitejs/plugin-vue
# PWA
npm install -D vite-plugin-pwa
# SVG as Component
npm install -D vite-plugin-svg-loader
# Visualize bundle
npm install -D rollup-plugin-visualizer
# Legacy browser support
npm install -D @vitejs/plugin-legacy
Cấu hình nhiều plugin
// vite.config.js
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { VitePWA } from 'vite-plugin-pwa'
import { visualizer } from 'rollup-plugin-visualizer'
export default defineConfig({
plugins: [
react(),
VitePWA({
registerType: 'autoUpdate',
includeAssets: ['favicon.ico'],
manifest: {
name: 'My App',
short_name: 'App',
theme_color: '#646cff',
}
}),
visualizer({
open: true,
filename: 'dist/stats.html',
})
]
})
Vite + React: Ví dụ thực tế
Tạo một dự án React hoàn chỉnh với Vite:
npm create vite@latest todo-app -- --template react-ts
cd todo-app
npm install
npm run dev
Mở src/App.tsx và viết một Todo app đơn giản:
import { useState } from 'react'
import './App.css'
interface Todo {
id: number
text: string
completed: boolean
}
function App() {
const [todos, setTodos] = useState<Todo[]>([])
const [input, setInput] = useState('')
const addTodo = () => {
if (!input.trim()) return
setTodos([...todos, {
id: Date.now(),
text: input,
completed: false
}])
setInput('')
}
const toggleTodo = (id: number) => {
setTodos(todos.map(todo =>
todo.id === id ? { ...todo, completed: !todo.completed } : todo
))
}
return (
<div className="app">
<h1>Todo App with Vite + React</h1>
<div className="input-group">
<input
value={input}
onChange={e => setInput(e.target.value)}
onKeyDown={e => e.key === 'Enter' && addTodo()}
placeholder="Thêm việc cần làm..."
/>
<button onClick={addTodo}>Thêm</button>
</div>
<ul className="todo-list">
{todos.map(todo => (
<li
key={todo.id}
onClick={() => toggleTodo(todo.id)}
className={todo.completed ? 'completed' : ''}
>
{todo.text}
</li>
))}
</ul>
<p className="stats">
Đã hoàn thành: {todos.filter(t => t.completed).length} / {todos.length}
</p>
</div>
)
}
export default App
Chạy npm run build để build production, rồi npm run preview để xem kết quả.
Kết luận
Vite đã thay đổi hoàn toàn cách chúng ta phát triển web. Với tốc độ vượt trội, cấu hình đơn giản, và hệ sinh thái plugin phong phú, Vite xứng đáng là lựa chọn số một cho mọi dự án frontend hiện nay.
Lợi ích chính:
- Tốc độ: Dev server khởi động < 1 giây, HMR tức thì
- Đơn giản: Zero config cho hầu hết dự án
- Linh hoạt: Hỗ trợ React, Vue, Svelte, Solid, và nhiều framework khác
- Hiện đại: Tận dụng ES Modules, TypeScript, CSS Modules
- Production-ready: Bundle nhỏ gọn, code splitting, tree-shaking
Bắt đầu ngay hôm nay!
npm create vite@latest my-first-vite-app -- --template react
cd my-first-vite-app
npm install
npm run dev
Chỉ với 3 lệnh, bạn đã có một dự án React với dev server siêu nhanh. Hãy trải nghiệm sự khác biệt mà Vite mang lại!
Bài viết tiếp theo: Cấu hình Vite cho dự án React lớn — multi-environment, Docker, CI/CD.