Vite · Part 8 — Env Vars & Modes
Environment variables in Vite: import.meta.env, the .env file cascade and priority, the critical VITE_ prefix that gates what reaches the client, built-in vars, define vs env, and custom modes. With an env & mode resolver.
Biến môi trường là nơi một hiểu lầm nhỏ thành rò rỉ bí mật. Mô hình của Vite đơn giản và an toàn mặc định — nhưng chỉ khi bạn hiểu luật tiền tố VITE_.
Chọn một mode để xem file .env nào tải, rồi nghiên cứu cổng tiền tố bảo vệ bí mật:
1. import.meta.env
Vite phơi env var trên import.meta.env (không phải process.env — không có Node trong trình duyệt):
const apiUrl = import.meta.env.VITE_API_URL;
Hằng có sẵn:
| Var | Giá trị |
|---|---|
import.meta.env.MODE | chuỗi mode hiện tại |
import.meta.env.DEV | true khi dev |
import.meta.env.PROD | true khi build |
import.meta.env.BASE_URL | config base của bạn |
import.meta.env.SSR | true khi SSR |
2. Cổng tiền tố VITE_ — luật bảo mật
Đây là luật quan trọng nhất cả phần: chỉ biến có tiền tố VITE_ mới được phơi cho code client.
# .env
VITE_API_URL=https://api.example.com # ✓ reaches the browser
DB_PASSWORD=super-secret # ✗ stays server-only, never bundled
import.meta.env.VITE_API_URL; // "https://api.example.com"
import.meta.env.DB_PASSWORD; // undefined — by design
Vì sao quan trọng: bundle client của bạn gửi tới trình duyệt mọi người dùng. Mọi thứ trong đó là công khai. Tiền tố buộc bạn chủ động chọn từng giá trị phơi ra, nên một STRIPE_SECRET_KEY lạc trong .env không bao giờ vô tình lọt vào JS.
Không có cái gọi là env var “bí mật” phía client. Mọi thứ phơi cho trình duyệt đều đọc được. Giữ bí mật thật trên server/edge và gọi từ client.
3. Tầng file .env
Vite tải nhiều file .env và gộp theo ưu tiên. Từ cao xuống thấp:
.env.[mode].local ← mode-specific, git-ignored (highest)
.env.[mode] ← mode-specific
.env.local ← all modes, git-ignored
.env ← all modes (lowest)
- File
.localđược git-ignore — để giá trị riêng máy và secret cục bộ ở đó. - File theo mode (
.env.production) chỉ tải trong mode đó. - File ưu tiên cao ghi đè file thấp khi xung đột.
Commit .env (mặc định chung) và .env.example (mẫu); đừng bao giờ commit .env.local hay .env.*.local.
4. Mode
Một mode là môi trường có tên, điều khiển file .env.[mode] nào tải và giá trị import.meta.env.MODE:
- → mode
development - → mode
production - → mode
staging(tải.env.staging)
Mode tùy chỉnh cho bạn ship bản staging trỏ tới API staging mà không đổi code — chỉ một file .env.staging.
5. define vs env var
Cả hai chèn giá trị lúc build, nhưng cho việc khác nhau:
- config chuỗi thay đổi theo môi trường, từ file
.env, truy cập quaimport.meta.env. - thay thế văn bản lúc biên dịch cho bất kỳ biểu thức nào, đặt trong config:
export default defineConfig({
define: {
__APP_VERSION__: JSON.stringify(process.env.npm_package_version),
__BUILD_TIME__: JSON.stringify(new Date().toISOString()),
},
});
Dùng define cho hằng biết lúc build (version, cờ build); dùng env var cho config theo môi trường. Nhớ giá trị define phải là chuỗi JSON-serializable.
6. Bài tập
1. Bạn thêm API_SECRET=abc123 vào .env và đọc import.meta.env.API_SECRET trong component — nó undefined. Vì sao, và tốt không?
Lời giải
Nó thiếu tiền tố VITE_, nên Vite không phơi cho code client — đúng vậy: secret không bao giờ nên vào bundle trình duyệt.
2. Cả .env và .env.production định nghĩa VITE_API_URL. Khi vite build, cái nào thắng?
Lời giải
.env.production — file theo mode ưu tiên cao hơn .env cơ bản.
3. Bạn cần một bản build nhắm backend staging mà không động code. Thiết lập sao?
Lời giải
Tạo .env.staging với VITE_API_URL=...staging... và chạy vite build --mode staging.
Nâng cao:trong resolver, chuyển mode và để ý file theo mode chỉ hiện cho mode đang chạy, còn .env và .env.local luôn tải.
Điểm chính
- Đọc env var qua
import.meta.env, không phảiprocess.env. - Chỉ biến tiền tố
VITE_tới client — rào chắn bí mật. - Không có env var bí mật phía client — giữ bí mật thật ở server.
- File
.envxếp tầng theo ưu tiên; file.localđược git-ignore. - Mode đổi file
.env.[mode]nào tải;definecho hằng lúc build.
Tiếp theo
Phần 9 — Plugin: API plugin tương thích Rollup, các hook bạn dùng, enforce và apply, và tự viết một plugin virtual-module.