Vite & SWC — Bộ Đồ Nghề "Xây Nhà" Siêu Tốc ⚡¶
Chào bạn! Khi làm web hiện đại, bạn sẽ nghe nhiều đến "Build Tool" (Công cụ đóng gói). Bài này sẽ giúp bạn hiểu tại sao chúng ta lại cần nó và tại sao bộ đôi Vite + SWC lại được yêu thích đến vậy.
Tại Sao Lại Cần Build Tool Vậy? 🤔¶
Trình duyệt web của chúng ta thực ra khá kén ăn. Nó không thể đọc hiểu trực tiếp những thứ "hiện đại" mà bạn viết:
- TypeScript: Phải có người dịch nó về JavaScript thuần thì trình duyệt mới hiểu.
- JSX (
<div>...</div>trong file JS): Cần được biến đổi thành các lệnh tạo giao diện thực tế (nhưReact.createElement(...)). - Quá nhiều file: Khi bạn chia code ra hàng chục, hàng trăm file nhỏ, trình duyệt sẽ rất mệt nếu tải từng file một. Cần có người gom chúng lại thành vài cục to (bundle).
- CSS: Các tính năng nâng cao của CSS cũng cần được biên dịch.
Build Tool sinh ra chính là để làm vị cứu tinh giải quyết tất cả các khâu "phiên dịch" và "đóng gói" này!
Vite — Vị Vua Tốc Độ Mới 🏎️¶
Nỗi Khổ Ngày Xưa (Với Webpack)¶
Trước đây, Webpack là công cụ quốc dân. Nhưng nó có một nhược điểm chí mạng: Mỗi khi bạn bật máy lên code, nó phải đọc hết TẤT CẢ các file, xây dựng bản đồ liên kết, đóng gói thành 1 cục rồi mới mở web cho bạn xem.
- Hậu quả: Project to một tí là bạn phải ngồi nhìn màn hình load 30-60 giây. Sửa một dòng code cũng mất 2-10 giây để thấy thay đổi. Rất tụt mood!
Cách Vite Giải Cứu Thế Giới¶
Vite thông minh hơn bằng cách chia làm 2 chế độ làm việc hoàn toàn khác nhau:
1. Lúc Đang Code Ở Máy Nhà (Development Mode) — Không Thèm Đóng Gói¶
- Thay vì gom mọi thứ lại, Vite tận dụng khả năng đọc mã module mới của trình duyệt.
- Trình duyệt gọi file nào, Vite dịch đúng file đó rồi ném qua ngay lập tức.
- Kết quả: Khởi động dự án gần như tức thì (< 1 giây). Bấm lưu code một phát, giao diện cập nhật ngay lặp tức (< 100ms) bằng tính năng HMR. Sướng rân người!
2. Lúc Đưa Lên Mạng Thật (Production Mode) — Gói Ghém Kỹ Càng¶
Khi bạn chuẩn bị tung sản phẩm ra thị trường, Vite sẽ dùng một công cụ tên là Rollup để làm nhiệm vụ:
- Dọn rác (Tree-shaking): Quét xem đoạn code nào viết ra mà không xài tới thì chặt bỏ hết cho nhẹ.
- Chia nhỏ (Code splitting): Không dồn hết vào 1 cục, mà chia thành từng phần nhỏ để người dùng mở trang nào thì tải phần đó thôi (Lazy loading).
- Nén siêu nhỏ (Minification): Bóp dung lượng code lại bé nhất có thể.
- Kết quả cuối cùng sẽ được bỏ gọn gàng vào thư mục
dist/.
Nghía Qua File Cấu Hình (vite.config.ts) ⚙️¶
// web/vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react-swc'; // Thay vì xài đồ cũ, mình xài SWC siêu tốc
export default defineConfig({
plugins: [react()],
server: {
// Port mặc định là 5173, khỏi cần ghi
proxy: {
// MẸO HAY: Tránh bị lỗi mạng CORS khi code ở nhà
// Nếu Web của bạn gọi đường link bắt đầu bằng /api (VD: /api/groups)
// Vite sẽ tự lén chuyển hướng nó sang máy chủ API thật (http://localhost:8787/groups)
'/api': {
target: 'http://localhost:8787',
rewrite: (path) => path.replace(/^\/api/, ''), // Xóa đi chữ /api cho đúng địa chỉ nhà API
},
},
},
build: {
outDir: 'dist', // Chỗ chứa đồ sau khi đóng gói xong
sourcemap: false, // Không cần tạo bản đồ lỗi khi lên mạng thật cho nhẹ
},
});
Lưu ý: Cái proxy này chỉ xài lúc code trên máy thôi nhé. Lên mạng thật thì Frontend sẽ gọi thẳng tắp đến API luôn.
Biến Môi Trường (Chìa Khóa Nhà) 🔑¶
Trong Vite, mọi biến bạn muốn trình duyệt đọc được phải bắt đầu bằng chữ VITE_:
# File .env.local (Cấm đưa lên mạng nhé)
VITE_API_URL=http://localhost:8787
VITE_TURNSTILE_SITE_KEY=1x00000000000000000000AA
Nhắc nhở bảo mật
Vì những biến bắt đầu bằng VITE_ sẽ bị lộ ra ngoài cho tất cả người dùng web xem được, nên KHÔNG BAO GIỜ được nhét mật khẩu hay chìa khóa bí mật vào đây nhé!
SWC — Cỗ Máy Dịch Thuật Động Cơ Tên Lửa 🚀¶
Tại Sao "Đá" Babel Để Chọn SWC?¶
Trước đây, người ta hay dùng Babel để dịch code. Nhưng Babel được viết bằng ngôn ngữ JavaScript. Trớ trêu thay, dùng JavaScript để đi biên dịch lại JavaScript thì rất chậm!
SWC (Speedy Web Compiler) ra đời và thay đổi cuộc chơi vì nó được viết bằng ngôn ngữ Rust:
- Nhanh khủng khiếp: Tốc độ cao hơn Babel từ 20 đến 70 lần!
- Tích hợp sẵn: Nó tự hiểu được TypeScript và JSX luôn mà không cần cài rườm rà.
- Với một dự án khổng lồ (hơn 1000 file), SWC có thể bóp thời gian build từ 1 phút xuống chỉ còn khoảng 3-5 giây.
Trong dự án này, thay vì xài plugin React thông thường (@vitejs/plugin-react), chúng ta dùng bản nạp "Nitro" của nó là @vitejs/plugin-react-swc để kích hoạt sức mạnh dịch code, biến đổi giao diện và cập nhật nóng (HMR).
Lướt Qua File Cấu Hình TypeScript (tsconfig.json) 📝¶
File này nhìn thì loằng ngoằng, nhưng bạn chỉ cần hiểu một ý chính thôi:
{
"compilerOptions": {
// Mấy cái râu ria: Báo cho biết là mình xài phiên bản JS mới (ES2020) và React (react-jsx)
"target": "ES2020",
"jsx": "react-jsx",
// ĐIỂM SÁNG GIÁ NHẤT NẰM Ở ĐÂY:
"moduleResolution": "bundler",
"noEmit": true,
// Dòng noEmit này nghĩa là: "Này TypeScript, mày chỉ việc soi lỗi chính tả (type-check) cho tao thôi. Còn việc vác code đi biên dịch thì tao giao cho thằng Vite/SWC làm rồi!"
// Mấy cái bật chế độ "Bảo vệ khó tính" (strict) để code chuẩn chỉ hơn
"strict": true
}
}
Những Câu Lệnh Sinh Tồn (Build Commands) 🛠️¶
Thuộc lòng mấy câu này để làm việc mỗi ngày nhé:
# Bật server để ngồi code (Có sẵn chức năng lưu là ăn ngay - HMR)
npm run dev
# Kiểm tra lỗi chính tả TypeScript và Đóng gói code thành phẩm
npm run build
# (Thằng này sẽ tạo ra thư mục dist/)
# Coi thử cái cục dist/ vừa đóng gói lên trình duyệt xem có lỗi gì không
npm run preview
# Bơm thẳng cục dist/ đó lên máy chủ Cloudflare Pages
npm run deploy
Thành Quả (Output Structure) 📦¶
Sau khi chạy lệnh npm run build, bạn sẽ thu được một thư mục dist/ có dạng như vầy:
dist/
index.html ← Cửa chính đi vào web (Ứng dụng 1 trang - SPA)
assets/
index-Bx7k9mNp.js ← Bộ não của web
index-CqL2rWxY.css ← Lớp áo trang trí (CSS)
vendor-DnM3pRqT.js ← Đồ nghề của bên thứ 3 (như thư viện React)
Tại sao tên file lại có mấy cái mã loằng ngoằng ở cuối (hash)? Đây là chiêu "Đánh lừa bộ nhớ đệm" (cache busting). Trình duyệt hay lưu file cũ lại cho nhẹ máy. Nhờ có cái mã ngẫu nhiên này, mỗi khi bạn sửa code, mã sẽ đổi thành chuỗi khác. Trình duyệt thấy tên file lạ sẽ hiểu là có bản cập nhật mới và ngoan ngoãn tải về, nhờ đó người dùng sẽ không bao giờ bị dính lỗi xem phiên bản cũ!