任何稍具规模的项目,都不可能只在一个环境里从头跑到尾。本地开发时,接口地址是 http://localhost:8080;提测后,要指向测试服务器的 https://test-api.example.com;预发布要切到 https://staging-api.example.com;上线后自然用正式域名 https://api.example.com。如果每次切换环境都要手动改代码里的 URL,不仅繁琐,还容易出事故——比如把测试数据带到了生产环境。
Vue 项目借助 Vite 的环境变量机制,可以做到一次配置,按环境自动切换,开发、测试、预发布、生产互不干扰。
1. 环境变量文件的约定
Vite 使用 dotenv 来加载环境变量。在项目根目录下,可以创建以下文件:
.env # 所有环境都会加载的公共变量
.env.local # 本地私密配置(应加入 .gitignore)
.env.development # 开发环境(vite 或 vite dev 时加载)
.env.production # 生产环境(vite build 时加载)
.env.staging # 自定义的预发布环境
文件名的后半段对应 Vite 的 模式(mode)。默认情况下,vite 或 vite dev 命令运行在 development 模式,vite build 运行在 production 模式。如果需要其他模式(比如预发布),可以显式指定 --mode staging:
# 开发
npm run dev # 默认 development 模式
# 构建测试包(可指向测试环境的接口)
npm run build -- --mode development # 模拟测试环境构建
# 构建预发布包
npm run build -- --mode staging
# 构建生产包
npm run build # 默认 production 模式
一个常见的 package.json 脚本配置:
{
"scripts": {
"dev": "vite",
"build:test": "vite build --mode development",
"build:staging": "vite build --mode staging",
"build": "vite build"
}
}
这样,通过不同的构建命令,就能加载对应 .env 文件中的变量。
2. 变量的命名与使用
变量命名必须带 VITE_ 前缀,否则不会被暴露给客户端代码。这是为了防止意外地将服务器端私密变量泄露到前端。
示例 .env.development:
VITE_API_BASE_URL = http://localhost:3000/api
VITE_APP_TITLE = 本地开发环境
示例 .env.staging:
VITE_API_BASE_URL = https://staging-api.example.com
VITE_APP_TITLE = 预发布环境
示例 .env.production:
VITE_API_BASE_URL = https://api.example.com
VITE_APP_TITLE = 生产环境
在 Vue 组件或 JS 代码中,可通过 import.meta.env.VITE_XXX 访问:
// 封装的 axios 实例
import axios from 'axios'
const request = axios.create({
baseURL: import.meta.env.VITE_API_BASE_URL,
timeout: 10000
})
在模板中也可以直接使用:
<template>
<div>
<h1>{{ import.meta.env.VITE_APP_TITLE }}</h1>
</div>
</template>
这样就实现了同一个变量名,在不同构建模式下自动取不同的值。
3. 变量的补充与覆盖规则
环境变量文件的加载顺序是:.env(公共) -> .env.[mode](对应模式) -> .env.local(本地覆盖) -> .env.[mode].local。后加载的变量会覆盖前面同名的变量。
建议的做法是:
- 将非敏感的公共变量放在
.env中(如VITE_APP_VERSION)。 - 各模式差异变量放在
.env.development、.env.production等文件中,并提交到仓库,这样所有开发者的环境保持一致。 - 包含个人密钥、本地端口偏好的私人配置,放在
.env.local(或.env.development.local、.env.production.local)中,并务必加入.gitignore。
# .gitignore 中应包含
.env.local
.env.*.local
4. 真实场景中的注意事项
- 环境变量是构建时注入的
import.meta.env.VITE_XXX 在打包时会被直接替换为字符串字面量,类似于 C 语言的宏。这意味着你不能在代码运行时动态切换环境——一旦打包完成,里面的 URL 就固定了。如果需要运行时切换,应该使用后端返回的配置接口,而不是前端环境变量。
- 敏感信息不要放进前端环境变量
哪怕带有 VITE_ 前缀的变量最终都会被打包进 JS 文件,用户可以轻易看到。任何第三方密钥、私密令牌都不应该出现在前端环境变量中,应通过后端 API 间接获取或使用 BFF(Backend For Frontend)层处理。
- 善用
.env.example
在仓库中提供一个 .env.example 文件,列出项目需要的所有环境变量及其说明,但不包含真实值。新成员克隆项目后,复制一份进行本地配置:
# .env.example
VITE_API_BASE_URL = 接口地址,本地开发一般为 http://localhost:3000/api
VITE_APP_TITLE = 应用标题
- 模式与 Git 分支协同
通常不同环境对应不同的部署分支:develop 分支部署测试环境,release 分支部署预发布,master/main 分支部署生产。CI/CD 脚本中通过 --mode 参数指定构建模式,实现自动化环境切换。
5. 不止是 URL,环境隔离的更多用途
多环境变量的价值远不止切换 API 地址。常见用法包括:
- 功能开关:比如预发布环境开启日志上报,生产环境不开。
- 调试工具:开发环境注入
VITE_ENABLE_DEVTOOLS = true。 - 第三方服务配置:不同环境使用不同的大数据埋点 ID、地图 API Key 等。
通过合理规划环境变量文件,你的 Vue 项目可以做到一份代码,多环境适配,彻底告别改一行代码发一个包的混乱局面。