环境变量完全指南:用 Vite 把「配置」玩出花
关键词:Vite / dotenv / 多环境 / CI/CD / 安全
预计阅读:10 min
附源码、脑图、踩坑清单,可直接落地到项目
一、为什么 2025 了还在聊环境变量?
- 本地调 HTTPS 接口?
- 灰度发布要动态开关?
- CI 里注入密钥,又不想提交到仓库?
“一行配置,全局生效” 才是高效团队的共同特征。Vite 把 Webpack 时代“配到吐血”的体验压缩成了 3 个文件 + 2 条命令,但 90% 的开发者只用了 10% 的功能。今天这篇,带你一次吃透。
二、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
# 功能开关
VITE_ENABLE_MOCK=true
3. 在代码里“零成本”读取
// 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.config.ts 里“ Node 侧”读取
import { defineConfig, loadEnv } from 'vite'export default defineConfig(({ mode }) => {// 把当前 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. 命令行一键覆盖
# 本地临时连线上接口
VITE_API_BASE=https://prod.api.com vite
适合联调“最后一公里”,无需改文件。
2. CI/CD 注入密钥(GitHub Actions 示例)
- name: Buildrun: npm run buildenv:VITE_API_BASE: ${{ secrets.API_BASE }}VITE_SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
3. 类型安全:让 TypeScript 认识你的变量
// env.d.ts
/// <reference types="vite/client" />interface ImportMetaEnv {readonly VITE_API_BASE: stringreadonly VITE_DEBUG: 'true' | 'false'readonly VITE_ENABLE_MOCK: 'true' | 'false'
}interface ImportMeta {readonly env: ImportMetaEnv
}
编码阶段自动补全 + 编译期检查,杜绝手抖。
五、常见踩坑清单(收藏级)
现象 | 原因 | 正确姿势 |
---|---|---|
process.env.XXX 为 undefined | 客户端没有 process 对象 | 用 import.meta.env.XXX |
变量未注入 | 没以 VITE_ 开头 | 统一加前缀 |
生产包还是走的 dev 地址 | 构建时 mode 不对 | vite build --mode production |
.env.local 提交到仓库 | 被 Git 追踪 | 写进 .gitignore |
敏感 key 被打包 | 直接写了 VITE_SECRET | 只在服务端使用,切勿前缀 VITE_ |
六、一张图总结(保存即可)
graph TDA[命令行 vite --mode xxx] --> B[dotenv 加载]B --> C{.env}B --> D{.env.[mode]}C --> E[合并环境变量]D --> EE --> F[客户端 import.meta.env]E --> G[Node 侧 loadEnv]F --> H[业务代码/axios/router]G --> I[vite.config.ts 代理 define]
七、结语
环境变量是“最被低估”的生产力工具。Vite 把复杂度留在内部,把优雅留给我们:
“写最少的配置,做最灵活的部署。”
把这篇收藏起来,下次从 0 到 1 搭项目,直接复制文件夹 + 脚本,5 分钟搞定多环境。
祝你玩得开心,上线不踩坑!