jvinhit//lab

Search posts

Type to search across journal entries.

navigate open esc close

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.

3 MIN READ

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:

VarGiá trị
import.meta.env.MODEchuỗi mode hiện tại
import.meta.env.DEVtrue khi dev
import.meta.env.PRODtrue khi build
import.meta.env.BASE_URLconfig base của bạn
import.meta.env.SSRtrue 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 qua import.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.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.env.local luôn tải.


Điểm chính

  • Đọc env var qua import.meta.env, không phải process.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 .env xếp tầng theo ưu tiên; file .local được git-ignore.
  • Mode đổi file .env.[mode] nào tải; define cho 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, enforceapply, và tự viết một plugin virtual-module.