关键词:Vite / dotenv / 多环境 / CI/CD / 安全
预计阅读:10 min
附源码、脑图、踩坑清单,可直接落地到项目
一、为什么 2026 了还在聊环境变量?
当你的项目需要应对不同场景时,是否遇到过这些烦恼?
- 本地开发却需要调试 HTTPS 接口?
- 灰度发布时,要动态开关某些新功能?
- 持续集成(CI)流程中,如何安全地注入密钥,避免将其提交到代码仓库?
“一行配置,全局生效” 是高效团队的共同特征。相较于 Webpack 时代复杂的配置,Vite 已经将体验优化至极简,仅需几个文件与命令即可完成。然而,大多数开发者可能只使用了其 10% 的功能。本文将带你深入理解并掌握 Vite 环境变量的完整链路。
二、5 张脑图速览全链路
为了让你快速建立全局认知,我们先用一张表格梳理核心概念与流程:
| 维度 |
开发 |
测试 |
预发 |
生产 |
| 启动命令 |
vite |
vite --mode test |
vite --mode staging |
vite build |
| 加载文件 |
.env + .env.development |
.env + .env.test |
.env + .env.staging |
.env + .env.production |
| 变量前缀 |
VITE_* |
VITE_* |
VITE_* |
VITE_* |
| 客户端取值 |
import.meta.env |
✅ |
✅ |
✅ |
| Node 侧取值 |
loadEnv(mode, cwd()) |
✅ |
✅ |
✅ |
三、从 0 搭建一个“多环境”项目
1. 初始化项目
npm create vite@latest vite-env-demo --template vue-ts
cd vite-env-demo
2. 创建环境文件(按规范命名)
在项目根目录下,创建如下文件结构:
├─ .env # 公共变量(所有环境共享)
├─ .env.development # 本地开发环境
├─ .env.test # 测试环境
├─ .env.staging # 预发布环境
├─ .env.production # 线上生产环境
以下是 .env.development 文件的示例内容:
# 接口基础地址
VITE_API_BASE=https://dev.api.example.com
# 调试模式开关
VITE_DEBUG=true
# 是否启用 Mock 数据
VITE_ENABLE_MOCK=true
3. 在客户端代码中读取
在业务代码中,你可以通过 import.meta.env 直接访问这些以 VITE_ 为前缀的变量。
// src/utils/request.ts
const baseURL = import.meta.env.VITE_API_BASE as string
const enableMock = import.meta.env.VITE_MOCK === 'true'
export const request = axios.create({ baseURL })
4. 在 Vite 配置文件中读取(Node.js 侧)
有时,你需要在 vite.config.ts 中根据环境变量动态配置,例如设置代理或定义全局常量。
import { defineConfig, loadEnv } from 'vite'
export default defineConfig(({ mode }) => {
// 加载并合并当前模式下的所有环境变量
const env = loadEnv(mode, process.cwd(), '')
return {
// 将变量注入到 `define` 选项中,构建时会被静态替换
define: {
__APP_VERSION__: JSON.stringify(process.env.npm_package_version),
__API_URL__: JSON.stringify(env.VITE_API_BASE),
},
server: {
// 根据环境变量动态配置代理
proxy: env.VITE_ENABLE_MOCK
? {}
: {
'/api': {
target: env.VITE_API_BASE,
changeOrigin: true,
rewrite: (p) => p.replace(/^\/api/, ''),
},
},
},
}
})
四、高阶玩法:动态“插拔”配置
1. 命令行一键覆盖
你可以在启动命令前直接设置环境变量,临时覆盖文件中的配置,这在进行特定场景联调时非常方便。
# 在本地开发时,临时连接到生产环境的 API
VITE_API_BASE=https://prod.api.com vite
适用场景:临时联调、快速验证,无需修改任何配置文件。
2. CI/CD 中注入密钥(GitHub Actions 示例)
在持续集成/持续部署流程中,安全地注入密钥是标准实践。以下是一个 GitHub Actions 的配置示例:
- name: Build
run: npm run build
env:
VITE_API_BASE: ${{ secrets.API_BASE }}
VITE_SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
3. 类型安全:让 TypeScript 认识你的变量
为了获得更好的开发体验和编译时检查,你可以扩展 ImportMetaEnv 接口。
// env.d.ts
/// <reference types="vite/client" />
interface ImportMetaEnv {
readonly VITE_API_BASE: string
readonly VITE_DEBUG: 'true' | 'false'
readonly VITE_ENABLE_MOCK: 'true' | 'false'
// ... 声明你的其他环境变量
}
interface ImportMeta {
readonly env: ImportMetaEnv
}
价值:编码时获得自动补全提示,编译阶段进行类型检查,有效避免因变量名拼写错误导致的运行时问题。
五、常见踩坑清单(收藏级)
为了避免你在实践中走弯路,这里整理了一份常见问题与解决方案:
| 现象 |
原因 |
正确姿势 |
process.env.XXX 为 undefined |
在浏览器客户端中不存在 process 对象 |
使用 Vite 提供的 import.meta.env.XXX |
| 变量在代码中读取不到 |
环境变量名称没有以 VITE_ 开头 |
所有需要在客户端暴露的变量,必须统一以 VITE_ 为前缀 |
| 生产环境构建的包,API 地址仍是开发环境 |
构建时未指定正确的 mode,默认使用了 development |
使用 vite build --mode production 明确指定模式 |
.env.local 等文件被意外提交到 Git 仓库 |
未将其添加到 .gitignore 中 |
将 .env.local、.env.*.local 等文件加入 .gitignore |
| 敏感密钥(如 API Secret)被打包进前端代码 |
错误地将其设置为 VITE_SECRET 前缀 |
敏感信息应仅在服务端使用,绝对不要加 VITE_ 前缀暴露给客户端 |
六、一张图总结核心流程
通过下面的流程图,你可以清晰地看到从命令行到代码使用的完整链路:
graph TD
A[命令行 vite --mode xxx] --> B[dotenv 加载]
B --> C{.env 公共文件}
B --> D{.env.[mode] 环境文件}
C --> E[合并环境变量]
D --> E
E --> F[客户端 import.meta.env]
E --> G[Node 侧 loadEnv]
F --> H[业务代码/axios/router]
G --> I[vite.config.ts 代理/define]
七、结语
环境变量堪称是现代前端工程中“最被低估”的生产力工具之一。Vite 的设计哲学是将复杂性封装在工具内部,而将简洁与灵活留给开发者。掌握其环境变量机制,便能真正做到 “写最少的配置,做最灵活的部署”。
建议你将本文中的项目结构、配置示例和踩坑清单收藏起来。当下次需要从零搭建一个新项目时,直接复用这套模式,5 分钟内即可建立起健壮的多环境配置体系。希望这篇指南能帮助你更高效地开发,在云栈社区与更多开发者交流心得,祝你编码愉快,上线顺利!