Vite · Part 1 — The Mental Model & Your First Project
Why Vite is fast: native ESM in dev means no bundling on startup, while production still bundles with Rolldown. Scaffold your first project, understand dev vs build, and see the two-strategy design. With a dev-startup race demo.
Nếu bạn đến từ series Webpack, bạn biết nỗi đau nó giải quyết — và cái giá: dev server phải build cả app trước khi phục vụ một trang. Cược của Vite đơn giản hơn: khi dev, để trình duyệt tự ghép qua ES module native, và chỉ bundle thật khi production.
Kéo kích thước dự án và đua một bundler với khởi động dev của Vite:
1. Nhận thức cốt lõi
Trình duyệt hiện đại hỗ trợ ES module native — <script type="module"> và import/export chạy được luôn. Vậy khi dev, Vite không bundle:
- Nó khởi động dev server tức thì, bất kể kích thước app.
- Khi trình duyệt yêu cầu một module, Vite biến đổi đúng file đó rồi gửi đi.
- File bạn không bao giờ tải sẽ không bao giờ được xử lý.
Khởi động của bundler tăng theo codebase; của Vite gần như phẳng. Đó là khoảng cách bạn vừa thấy trong demo.
2. Hai chiến lược, có chủ đích
Đây là phần nhiều người bỏ lỡ: Vite dùng công cụ khác nhau cho dev và prod.
| Giai đoạn | Chiến lược | Vì sao |
|---|---|---|
| dev | ESM native, không bundle | khởi động tức thì, biến đổi từng file |
| build | bundle bằng Rolldown | ESM không bundle = hàng nghìn request, quá chậm cho người dùng thật |
ESM native không bundle tốt cho bạn trên localhost, nhưng tệ cho người dùng trên mạng thật — mỗi import là một vòng round trip. Nên production nhận một bundle tối ưu đúng nghĩa.
Vite 8 (3/2026) hợp nhất chuỗi công cụ: Rolldown (bundler viết bằng Rust) lo build production, và Oxc lo biến đổi JS/TS — thay cặp esbuild + Rollup cũ.
3. Dựng dự án đầu tiên
npm create vite@latest my-app
# pick a framework (Vanilla, React, Vue, Svelte, Solid, Qwik…)
cd my-app
npm install
npm run dev
Dev server lên trong chưa tới một giây. Các script bạn sẽ sống cùng:
// package.json
{
"scripts": {
"dev": "vite", // start the dev server (native ESM)
"build": "vite build", // production bundle with Rolldown
"preview": "vite preview" // serve the built dist/ locally to sanity-check
}
}
preview quan trọng: nó phục vụ output production thật để bạn test thứ người dùng nhận, không phải trải nghiệm dev.
4. index.html là entry
Khác Webpack nơi entry là file JS, ở Vite index.html là điểm vào và nằm ở gốc dự án:
<!doctype html>
<html>
<body>
<div id="app"></div>
<!-- a normal module script — Vite takes it from here -->
<script type="module" src="/src/main.ts"></script>
</body>
</html>
Vite coi index.html là source: nó viết lại src="/src/main.ts" và lần theo đồ thị import từ đó. Không cần HtmlWebpackPlugin — HTML-first là tích hợp sẵn.
5. Hình dạng dự án
my-app/
├─ index.html ← entry (root, not in public/)
├─ public/ ← static files copied as-is (favicon, robots.txt)
├─ src/
│ ├─ main.ts ← app bootstrap
│ └─ ...
├─ vite.config.ts ← config (Part 2)
└─ package.json
Hai thư mục làm người mới vấp: public/ cho file phục vụ nguyên văn ở gốc (/favicon.svg), còn mọi thứ import từ src/ đi qua pipeline biến đổi của Vite. Chúng ta bàn kỹ asset ở Phần 7.
6. Bài tập
1. Vì sao khởi động dev của bundler chậm dần khi app lớn lên, còn Vite gần như không đổi?
Lời giải
Bundler build cả đồ thị phụ thuộc trước khi phục vụ (công việc ∝ kích thước app). Vite phục vụ source qua ESM native và chỉ biến đổi file trình duyệt thật sự yêu cầu.
2. Nếu ESM native nhanh thế khi dev, vì sao Vite vẫn bundle cho production?
Lời giải
ESM không bundle nghĩa là mỗi module một request mạng — ổn trên localhost, quá nhiều round trip cho người dùng thật. Production cần output bundle, minify, tách code (Rolldown).
3. Entry trong dự án Vite ở đâu, và vai trò của npm run preview?
Lời giải
index.html ở gốc dự án là entry. preview phục vụ dist/ đã build cục bộ để bạn test output production thật, không phải dev server.
Nâng cao:trong demo, đặt 3000 module và để ý tỉ lệ, rồi hạ xuống 50 — thời gian Vite gần như không đổi trong khi bundler tiến lại gần.
Điểm chính
- Khi dev, Vite phục vụ source qua ESM native — không bundle, khởi động tức thì.
- Khi production, Vite bundle bằng Rolldown (Vite 8) cho kết quả tối ưu.
- Khởi động dev gần như phẳng khi app lớn lên.
index.htmllà entry, ở gốc dự án.dev/build/previewlà ba lệnh bạn dùng hằng ngày.
Tiếp theo
Phần 2 — Giải phẫu vite.config.ts: object config từ trên xuống — root, base, plugins, resolve.alias, server, define, và cách mode định hình mọi thứ.