1. Vite环境变量基础解析
在Vite项目中,环境变量是配置不同运行环境的核心机制。与传统的Webpack配置不同,Vite采用了更现代的import.meta.env方案来处理环境变量。这个设计源于ES模块的原生支持,使得环境变量的使用更加直观和高效。
1.1 内置环境变量详解
Vite默认提供了四个基础环境变量,这些变量在项目启动时会被自动注入:
javascript复制{
MODE: 'development', // 当前运行模式
BASE_URL: '/', // 部署基础路径
PROD: false, // 是否生产环境
DEV: true // 是否开发环境
}
MODE变量特别值得关注,它决定了Vite会加载哪个环境配置文件。默认情况下,运行vite dev时MODE值为development,运行vite build时则为production。但我们可以通过命令行参数覆盖这个默认行为:
bash复制vite --mode staging # 将MODE设置为staging
1.2 环境变量的加载机制
Vite的环境变量系统遵循特定的加载优先级规则:
.env.[mode].local- 最高优先级,本地覆盖文件.env.[mode]- 指定模式的配置文件.env.local- 所有模式的本地覆盖.env- 通用环境变量
重要提示:所有
.local文件应该加入.gitignore,因为它们通常包含敏感信息。
2. 自定义环境变量实战
2.1 命名规范与使用限制
Vite对自定义环境变量有严格的命名要求:只有以VITE_开头的变量才会被暴露给客户端代码。这是出于安全考虑的设计,避免意外泄露敏感信息。
env复制# 正确的命名方式
VITE_API_URL=https://api.example.com
VITE_DEBUG=true
# 这些变量不会被客户端访问到
DB_PASSWORD=secret
API_KEY=123456
2.2 多环境配置实践
实际项目中,我们通常需要配置多个环境。假设我们有开发、测试和生产三个环境,可以这样组织文件:
code复制.env # 通用配置
.env.development # 开发环境专用
.env.test # 测试环境专用
.env.production # 生产环境专用
在package.json中配置对应的启动命令:
json复制{
"scripts": {
"dev": "vite",
"test": "vite --mode test",
"build": "vite build",
"preview": "vite preview"
}
}
2.3 环境变量智能提示
为了获得更好的开发体验,我们可以通过类型声明文件为自定义环境变量添加TypeScript支持:
typescript复制// vite-env.d.ts
interface ImportMetaEnv {
readonly VITE_API_BASE: string
readonly VITE_TIMEOUT: number
readonly VITE_ENABLE_ANALYTICS: boolean
}
interface ImportMeta {
readonly env: ImportMetaEnv
}
这样在代码中使用import.meta.env时就能获得自动补全和类型检查:
typescript复制const apiUrl = import.meta.env.VITE_API_BASE // 有类型提示
3. 高级应用场景
3.1 构建时变量替换
在生产构建时,Vite会直接静态替换import.meta.env为实际值。这意味着:
javascript复制// 源代码
console.log(import.meta.env.VITE_API_URL)
// 生产构建后可能变成
console.log("https://api.example.com")
这种设计带来了更好的性能,但也意味着你不能在运行时动态修改环境变量。
3.2 条件编译技巧
利用环境变量可以实现条件编译,这在多环境适配时非常有用:
javascript复制// 根据环境加载不同配置
const config = import.meta.env.DEV
? require('./config/dev')
: require('./config/prod')
// 或者使用更简洁的条件判断
if (import.meta.env.VITE_DEBUG) {
enableDebugTools()
}
3.3 与Docker的集成
在容器化部署时,我们通常通过Docker环境变量来注入配置:
dockerfile复制FROM node:16
WORKDIR /app
COPY . .
RUN npm install
ENV VITE_API_URL=$API_URL
CMD ["npm", "run", "build"]
然后通过docker-compose传递变量:
yaml复制services:
app:
build: .
environment:
- API_URL=https://api.prod.example.com
4. 常见问题与解决方案
4.1 环境变量未生效排查
当环境变量没有按预期工作时,可以按照以下步骤排查:
- 确认变量名以
VITE_开头 - 检查文件命名是否正确(如.env.production而非.env.prod)
- 验证加载顺序,后加载的文件会覆盖前者
- 确保没有意外的字符(如空格或引号)
env复制# 错误示例(值包含空格)
VITE_API_URL = https://api.example.com
# 正确写法
VITE_API_URL=https://api.example.com
4.2 生产环境变量保护
生产环境敏感信息应该通过以下方式保护:
- 使用CI/CD系统的secret管理
- 通过服务器环境变量注入,而非存储在文件中
- 确保.gitignore包含所有.local文件
bash复制# 通过命令行传递敏感变量
VITE_API_KEY=secret vite build
4.3 跨项目共享配置
对于大型项目,可以考虑将通用配置提取为单独模块:
javascript复制// src/config/env.js
export const env = {
apiBase: import.meta.env.VITE_API_BASE,
timeout: parseInt(import.meta.env.VITE_TIMEOUT || '5000'),
features: {
analytics: import.meta.env.VITE_ENABLE_ANALYTICS === 'true'
}
}
这样可以在整个项目中一致地访问环境变量,并添加必要的转换逻辑。
5. 性能优化建议
5.1 减少环境变量数量
过多的环境变量会影响构建性能,建议:
- 合并相关变量为JSON字符串
- 只在必要时使用环境变量
- 考虑使用配置文件替代大量变量
env复制# 合并前
VITE_FEATURE_A=true
VITE_FEATURE_B=false
VITE_FEATURE_C=true
# 合并后
VITE_FEATURES={"A":true,"B":false,"C":true}
5.2 合理使用.env文件
- 开发环境使用
.env.development,生产环境使用.env.production - 团队共享配置放在
.env,个人覆盖使用.env.local - 测试环境专用变量放在
.env.test
5.3 构建缓存策略
Vite会缓存.env文件解析结果。修改环境变量后,可能需要:
bash复制# 清除缓存并重新构建
vite --force
或者在配置文件中显式禁用缓存:
javascript复制// vite.config.js
export default {
cacheDir: false
}
6. 测试环境特殊处理
6.1 测试专用变量
为测试环境创建专用配置:
env复制# .env.test
VITE_API_MOCK=true
VITE_TEST_USER=admin
然后在测试脚本中指定模式:
json复制{
"scripts": {
"test": "vite --mode test && vitest"
}
}
6.2 端到端测试配置
对于Cypress等端到端测试,可以在测试代码中覆盖环境变量:
javascript复制// cypress/support/index.js
before(() => {
if (Cypress.env('MOCK_API')) {
cy.intercept('GET', '/api/*', { fixture: 'data.json' })
}
})
启动测试时传递变量:
bash复制CYPRESS_MOCK_API=true npm run test:e2e
7. 与前端框架的集成
7.1 React应用中的使用
在React组件中安全地使用环境变量:
jsx复制function App() {
return (
<div>
<h1>{import.meta.env.VITE_APP_TITLE}</h1>
<p>API Base: {import.meta.env.VITE_API_BASE}</p>
</div>
)
}
7.2 Vue中的最佳实践
Vue项目可以通过provide/inject全局共享环境变量:
javascript复制// main.js
app.provide('env', import.meta.env)
// 组件中使用
export default {
inject: ['env'],
created() {
console.log(this.env.VITE_API_BASE)
}
}
7.3 Svelte的特殊处理
Svelte需要在编译时访问环境变量:
svelte复制<script>
const apiUrl = import.meta.env.VITE_API_URL
</script>
<button on:click={() => fetch(apiUrl)}>
Call API
</button>
8. 安全注意事项
8.1 敏感信息保护
绝对不要在前端代码中暴露:
- API密钥
- 数据库凭证
- 加密密钥
- 内部服务地址
env复制# 错误示例(绝对禁止)
VITE_DB_PASSWORD=123456
VITE_AWS_SECRET=abcdef
8.2 CSP策略配置
即使使用VITE_前缀,也要设置合适的内容安全策略:
javascript复制// vite.config.js
export default {
server: {
headers: {
'Content-Security-Policy': "default-src 'self'"
}
}
}
8.3 生产环境审计
定期检查生产环境构建结果,确保:
- 没有意外暴露的敏感变量
- 所有环境变量都被正确替换
- 没有调试代码被包含
bash复制# 检查构建产物中的环境变量
grep -r "import.meta.env" dist/
9. 调试技巧
9.1 查看已加载变量
在开发过程中,可以临时添加调试代码:
javascript复制console.log('Loaded env:', JSON.stringify(import.meta.env, null, 2))
或者在Vite配置中添加日志:
javascript复制// vite.config.js
export default {
configureServer(server) {
server.middlewares.use((req, res, next) => {
console.log('Env:', process.env)
next()
})
}
}
9.2 源映射配置
确保生产构建时能正确映射源文件:
javascript复制// vite.config.js
export default {
build: {
sourcemap: true
}
}
10. 进阶主题
10.1 自定义加载逻辑
通过Vite插件可以扩展环境变量处理:
javascript复制// vite.config.js
export default {
plugins: [{
name: 'env-loader',
config(config, env) {
return {
define: {
'__APP_VERSION__': JSON.stringify(process.env.npm_package_version)
}
}
}
}]
}
10.2 环境变量验证
使用zod等库验证环境变量:
javascript复制// src/env.js
import { z } from 'zod'
const envSchema = z.object({
VITE_API_URL: z.string().url(),
VITE_TIMEOUT: z.number().positive()
})
export const env = envSchema.parse(import.meta.env)
10.3 与后端服务协同
前后端共享环境变量命名:
env复制# 前端 .env
VITE_API_URL=/api
# 后端 .env
API_BASE_URL=/api
这样保持开发和生产环境的一致性。