Vite 环境变量与 import.meta.env

说明 Vite 的 mode、.env 文件加载顺序、VITE_ 前缀与 import.meta.env 在开发/构建中的替换语义。

#type / concept #status / growing #tech / dev / frontend #resource / javascript

[!info] 关联笔记

Vite 环境变量与 import.meta.env

这个概念为什么出现

前端不能像服务端那样随便把密钥打进浏览器包。项目又需要:

  • 开发 / 预发 / 生产 API 地址不同
  • 功能开关随环境变化
  • 构建期注入版本号

Vite 用 mode + .env* + import.meta.env 给出约定,而不是让业务代码直接读任意 process.env

[!abstract] 一句话理解 只有暴露给客户端的变量(默认 VITE_ 前缀)会进入 import.meta.env,并在构建时被静态替换;mode 决定加载哪套 .env 文件。

最小可运行示例

场景:库存后台在本地连 mock,预发连测试网关

# .env
VITE_APP_TITLE=库存后台

# .env.development
VITE_API_BASE_URL=http://localhost:3000

# .env.staging
VITE_API_BASE_URL=https://api.staging.example.com
// src/api/client.ts
// 业务意图:所有列表请求打到当前环境的 API 根路径。
// 教学点:只读取 VITE_ 变量;缺省时要显式处理,不能假设一定有值。
const apiBase = import.meta.env.VITE_API_BASE_URL

export async function fetchLowStockItems() {
  if (!apiBase) {
    // 失败路径:配置缺失应尽早暴露,避免请求打到相对路径的错误服务
    throw new Error('VITE_API_BASE_URL is not defined')
  }
  const response = await fetch(`${apiBase}/inventory/low-stock`)
  if (!response.ok) {
    throw new Error(`low-stock request failed: ${response.status}`)
  }
  return response.json()
}

// 教学点:MODE/DEV/PROD 是内置键
export function envBanner() {
  return `${import.meta.env.VITE_APP_TITLE} @ ${import.meta.env.MODE}`
}

建议运行:

pnpm dev                 # mode=development,加载 .env + .env.development
pnpm build --mode staging
pnpm preview

期望:

dev 横幅类似:库存后台 @ development
staging 构建后 API 指向测试网关;
源码中不会出现未以 VITE_ 暴露的私密变量。

结合场景再看三个关注点

  1. 前缀是安全边界,不是风格偏好。
  2. mode 选文件NODE_ENV 不承担全部环境命名。
  3. 构建期替换:不要指望改服务器 env 文件就能改已构建的静态包。

核心规则

  1. 加载顺序(同名后者覆盖,细节以官方为准):.env.env.[mode].env.local / .env.[mode].local
  2. 客户端暴露:默认仅 VITE_*(可用 envPrefix 配置,但更要谨慎)
  3. 内置:MODEBASE_URLPRODDEVSSR
  4. TypeScript:在 vite-env.d.ts 扩展 ImportMetaEnv

边界与反直觉

  • 未定义的 import.meta.env.VITE_Xundefined,不自动抛错
  • .local 文件通常不入库,避免把个人密钥提交
  • 服务端密钥应放在 BFF/网关,不要 VITE_ 暴露

常见误区

[!warning] 常见误区:把 mode 当成 NODE_ENV 的别名 staging 可以是自定义 mode;生产构建时 NODE_ENV 仍可能是 production。以官方 mode 文档为准。

工程实践

  • API 根路径、Sentry DSN 等“本来就要进前端”的配置才用 VITE_
  • CI 用 --mode 选择环境,而不是手工改文件
  • monorepo 注意工具链重复加载 env 的冲突(见既有 debug 笔记)

本节总结

环境变量系统是 Vite 工程化的开关面板:mode 选文件,VITE_ 控暴露,import.meta.env 在构建时落地。

自测题

  1. 数据库密码能否放进 .env.production 并以 VITE_ 读取?
  2. 为什么改 .env 后有时要重启 dev server?
参考答案
  1. 不能;会打进前端包,等于公开。
  2. env 在服务启动时加载;多数改动不会热更新进已运行进程。

延伸阅读

资料类型支撑内容
Env Variables and Modes官方加载与前缀规则
创建于 2026/7/15 更新于 2026/7/15