前端项目经常需要根据运行环境用不同的配置。
比如:
开发环境 → http://localhost:8000
测试环境 → https://test-api.example.com
生产环境 → https://api.example.com如果直接把地址写死在代码里,后面维护起来会很麻烦。
环境变量就是为了解决这类问题的。
最简单的情况
Vite项目可以通过:
.env定义环境变量。
比如:
VITE_API_BASE_URL=https://api.example.com代码里:
const baseURL = import.meta.env.VITE_API_BASE_URL这样就可以读到配置了。
为什么VITE\_前缀很重要
Vite默认不会把所有环境变量都暴露给浏览器代码。
只有带了:
VITE_前缀的变量才会被注入到客户端代码里。
比如:
VITE_API_BASE_URL=https://api.example.com可以用。
但:
DATABASE_PASSWORD=123456不能因为写在.env里,就觉得它能在前端用。
这点非常重要。
前端环境变量不是秘密
这是很多刚开始用Vite的人容易犯的错。
比如:
VITE_API_KEY=abcdefg然后以为:
API Key放在.env里,就不会泄露。
这是不对的。
因为前端代码最终是要发给浏览器的。
用户打开网站之后,通过:
DevTools
Network
Source都能看到相关信息。
所以:
凡是前端代码能读到的环境变量,都应该当作公开信息。
真正的秘密应该放在后端。
不同环境用不同配置
一个比较常见的结构:
.env
.env.development
.env.production比如开发环境:
VITE_API_BASE_URL=http://localhost:8000生产环境:
VITE_API_BASE_URL=https://api.example.com构建的时候根据环境选对应的配置就行了。
这样同一份代码可以部署到不同环境。
环境变量最好集中管理
别在项目各个地方直接写:
import.meta.env.VITE_API_BASE_URL如果到处都有,以后改起来还是麻烦。
可以统一放一起:
export const config = {
apiBaseURL: import.meta.env.VITE_API_BASE_URL
}业务代码:
request(`${config.apiBaseURL}/users`)这样配置入口更明确。
TypeScript类型提示
Vite项目还可以给环境变量加类型声明。
比如:
interface ImportMetaEnv {
readonly VITE_API_BASE_URL: string
}
interface ImportMeta {
readonly env: ImportMetaEnv
}这样:
import.meta.env.VITE_API_BASE_URL就能获得TypeScript类型检查。
如果变量名写错了:
import.meta.env.VITE_API_BASEURLIDE能及时提醒你。
环境变量解决的是配置问题
我越来越觉得,环境变量本身并不复杂。
它解决的是:
同一套代码,在不同运行环境里用不同配置。
比如:
代码
↓
开发环境
↓
测试环境
↓
生产环境代码本身尽量不变。
变的是:
API地址
调试开关
功能开关
第三方服务配置这样部署过程会更清晰。
最后需要注意的一点
如果一个配置:
必须保密那它就不应该出现在前端。
比如:
数据库密码
Redis密码
服务器SSH密钥
私有API Secret这些应该由后端或者部署环境来管。
前端环境变量更多是用来放:
API地址
公开配置
功能开关
构建参数理解这一点之后,环境变量其实就很简单了。
对于Vue + Vite项目来说,我一般会尽量保持配置集中、命名清晰,同时始终把浏览器端的配置当作公开信息来设计。