环境变量与模式
原创2026/9/9...大约 6 分钟
环境变量与模式 🌍
在实际项目中,不同环境(开发、测试、生产)通常需要不同的配置:API 地址、密钥、是否开启调试等。Vite 内置了完善的环境变量与模式管理机制。
环境变量分类 💎
Vite 项目中通常有三类环境变量:
| 类型 | 来源 | 访问方式 |
|---|---|---|
| process.env | Node.js 原生环境变量 | 配置文件 / 构建脚本 |
| Vite 内置变量 | Vite 默认提供的变量 | 配置文件 / 客户端代码 |
| 自定义变量 | 项目根目录 .env.* 文件 | 以 VITE_ 开头的可在客户端访问 |
一、Vite 内置环境变量 💎
Vite 默认提供以下内置变量:
| 变量名 | 说明 |
|---|---|
import.meta.env.MODE | 当前运行模式(development / production) |
import.meta.env.BASE_URL | 应用的 base URL(对应 base 配置) |
import.meta.env.PROD | 是否为生产环境 |
import.meta.env.DEV | 是否为开发环境 |
import.meta.env.SSR | 是否为 SSR 渲染 |
// 在客户端代码中使用
if (import.meta.env.DEV) {
console.log('开发环境')
}
if (import.meta.env.PROD) {
console.log('生产环境')
}// 在 Vite 配置文件中使用(需要通过 env 对象访问)
import { defineConfig, loadEnv } from 'vite'
export default defineConfig(({ mode }) => {
const env = loadEnv(mode, process.cwd())
return {
server: {
port: env.VITE_PORT || 5173,
},
}
})二、.env 文件 💎
Vite 会自动加载项目根目录下的 .env.* 文件,作为环境变量的来源。
文件命名规范 👻
| 文件名 | 加载时机 | 适用场景 |
|---|---|---|
.env | 所有环境 | 通用配置 |
.env.local | 所有环境(git 忽略) | 本地私有配置 |
.env.[mode] | 仅对应模式 | 环境特定配置 |
.env.[mode].local | 仅对应模式(git 忽略) | 本地环境特定配置 |
优先级(高到低):
.env.[mode].local > .env.[mode] > .env.local > .env加载规则 👻
vite dev默认 mode 为development,会加载.env.development*vite build默认 mode 为production,会加载.env.production*--mode xxx可指定任意 mode,如vite build --mode staging
环境变量命名规范 👻
- ⚠️ 必须以
VITE_开头才能在客户端代码中访问 - 没有
VITE_前缀的变量只能在 Vite 配置文件 / Node 脚本中访问 - 推荐使用
UPPER_SNAKE_CASE命名
示例配置 👻
# .env(所有环境通用)
VITE_APP_TITLE=我的应用
VITE_DEFAULT_LANG=zh-CN# .env.development(开发环境)
VITE_API_BASE_URL=http://localhost:3000
VITE_USE_MOCK=true
NODE_ENV=development# .env.production(生产环境)
VITE_API_BASE_URL=https://api.yourcompany.com
VITE_USE_MOCK=false
NODE_ENV=production# .env.local(本地私有配置,不会被 git 跟踪)
# 常用于本地开发时覆盖通用配置
VITE_API_BASE_URL=http://192.168.1.100:3000# .env.test(测试环境)
VITE_API_BASE_URL=https://test-api.yourcompany.com# .env.staging(预发环境,--mode staging 时加载)
VITE_API_BASE_URL=https://staging-api.yourcompany.com三、在代码中使用 💎
客户端代码 👻
// 方式一:直接访问
const apiBase = import.meta.env.VITE_API_BASE_URL
const isDev = import.meta.env.DEV
const appTitle = import.meta.env.VITE_APP_TITLE
// 方式二:封装为工具函数
// src/utils/env.ts
export const env = {
API_BASE_URL: import.meta.env.VITE_API_BASE_URL,
APP_TITLE: import.meta.env.VITE_APP_TITLE,
USE_MOCK: import.meta.env.VITE_USE_MOCK === 'true',
IS_DEV: import.meta.env.DEV,
IS_PROD: import.meta.env.PROD,
MODE: import.meta.env.MODE,
}<template>
<div class="app">
<h1>{{ env.APP_TITLE }}</h1>
<p v-if="env.IS_DEV">开发环境</p>
</div>
</template>
<script setup lang="ts">
import { env } from '@/utils/env'
// 发起请求时使用
fetch(`${env.API_BASE_URL}/users`).then(/* ... */)
</script>HTML 中使用 👻
Vite 支持在 index.html 中使用环境变量:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<title><%= VITE_APP_TITLE %></title>
</head>
<body>
<div id="app"></div>
<script>
// 注意:环境变量只在编译时替换
console.log('当前环境:', '<%= MODE %>')
</script>
</body>
</html>TypeScript 类型声明 👻
为了让 TypeScript 识别自定义环境变量,需要在 src/env.d.ts 中声明:
/// <reference types="vite/client" />
interface ImportMetaEnv {
readonly VITE_APP_TITLE: string
readonly VITE_API_BASE_URL: string
readonly VITE_USE_MOCK: string
readonly VITE_DEFAULT_LANG: string
// 自定义变量...
}
interface ImportMeta {
readonly env: ImportMetaEnv
}四、define 配置 💎
如果想在客户端代码中使用没有 VITE_ 前缀的变量,需要使用 define 配置手动注入:
// vite.config.ts
import { defineConfig } from 'vite'
export default defineConfig({
define: {
// 在编译时进行文本替换
__APP_VERSION__: JSON.stringify('1.0.0'),
__BUILD_TIME__: JSON.stringify(new Date().toISOString()),
__DEV__: JSON.stringify(process.env.NODE_ENV === 'development'),
},
})// 在客户端代码中直接使用(无需 import)
console.log('版本:', __APP_VERSION__)
console.log('构建时间:', __BUILD_TIME__)define 的本质
define 本质上是编译时文本替换,并不是变量声明。要避免与变量名冲突:
define: {
// ❌ 错误:与变量名冲突会导致无限递归
// process: JSON.stringify('replaced'),
// ✅ 正确:使用 __ 双下划线包裹
__APP_VERSION__: JSON.stringify('1.0.0'),
}五、模式与命令行 💎
默认模式 👻
vite dev/vite→ mode:developmentvite build→ mode:productionvite preview→ mode:production
自定义模式 👻
# 加载 .env.staging
vite build --mode staging
# 加载 .env.preview
vite build --mode previewpackage.json 配置 👻
{
"scripts": {
"dev": "vite",
"dev:test": "vite --mode test",
"dev:staging": "vite --mode staging",
"build": "vue-tsc --noEmit && vite build",
"build:test": "vue-tsc --noEmit && vite build --mode test",
"build:staging": "vue-tsc --noEmit && vite build --mode staging",
"preview": "vite preview",
"preview:staging": "vite preview --mode staging"
}
}在配置文件中按模式区分 👻
import { defineConfig, loadEnv } from 'vite'
export default defineConfig(({ command, mode }) => {
const env = loadEnv(mode, process.cwd())
return {
define: {
__API_BASE__: JSON.stringify(env.VITE_API_BASE_URL),
},
server: {
port: mode === 'test' ? 5174 : 5173,
},
build: {
sourcemap: mode !== 'production',
minify: mode === 'production' ? 'esbuild' : false,
rollupOptions: {
output: {
// 不同环境使用不同的 chunk 名
entryFileNames: `assets/[name]-[hash].js`,
},
},
},
}
})六、envPrefix 配置 💎
默认情况下,只有 VITE_ 开头的变量会被注入到客户端。如果想使用其它前缀:
import { defineConfig } from 'vite'
export default defineConfig({
// 修改客户端可见变量前缀(默认 'VITE_')
envPrefix: 'APP_',
// 支持多个前缀
envPrefix: ['VITE_', 'APP_'],
})七、实战:多环境配置 💎
一个典型的多环境项目结构:
.env # 通用配置
.env.development # 开发
.env.development.local # 开发私有(git 忽略)
.env.staging # 预发
.env.staging.local # 预发私有
.env.production # 生产
.env.production.local # 生产私有# .env
VITE_APP_NAME=我的应用
VITE_DEFAULT_LANG=zh-CN# .env.development
VITE_API_BASE_URL=http://localhost:3000
VITE_ENABLE_MOCK=true
VITE_SHOW_LOGS=true# .env.staging
VITE_API_BASE_URL=https://staging-api.example.com
VITE_ENABLE_MOCK=false
VITE_SHOW_LOGS=true# .env.production
VITE_API_BASE_URL=https://api.example.com
VITE_ENABLE_MOCK=false
VITE_SHOW_LOGS=false// package.json
{
"scripts": {
"dev": "vite --mode development",
"dev:staging": "vite --mode staging",
"build:dev": "vue-tsc --noEmit && vite build --mode development",
"build:staging": "vue-tsc --noEmit && vite build --mode staging",
"build:prod": "vue-tsc --noEmit && vite build --mode production",
"preview:dev": "vite preview --mode development",
"preview:staging": "vite preview --mode staging"
}
}// src/utils/env.ts
export const env = {
APP_NAME: import.meta.env.VITE_APP_NAME,
API_BASE_URL: import.meta.env.VITE_API_BASE_URL,
ENABLE_MOCK: import.meta.env.VITE_ENABLE_MOCK === 'true',
SHOW_LOGS: import.meta.env.VITE_SHOW_LOGS === 'true',
MODE: import.meta.env.MODE,
IS_DEV: import.meta.env.DEV,
IS_PROD: import.meta.env.PROD,
}常见问题 💎
环境变量未生效 👻
- 检查变量名是否以
VITE_开头 - 修改
.env文件后必须重启 dev server - 检查
.env文件是否在项目根目录 - 确认
import.meta.env.VITE_XXX拼写正确
客户端能看到所有环境变量吗? 👻
不能! 只有以 VITE_ 开头的变量才会被注入到客户端。其余变量只能在 Vite 配置文件、构建脚本中访问。
敏感信息
不要在 .env.* 中存放真正的密钥,因为这些文件虽然不进入 git 仓库,但打包后 VITE_ 开头的变量会注入到客户端代码中。
真正的密钥应该:
- 存放在后端,通过接口返回
- 使用 CI/CD 的环境变量管理
- 在
.env.local中保存(且该文件加入.gitignore)
.gitignore 配置 👻
# 忽略所有 .local 类型的本地配置
.env.local
.env.*.local
# 但要保留非 local 配置的版本管理
!.env
!.env.development
!.env.staging
!.env.productionTypeScript 报错 👻
在 src/env.d.ts 中声明:
/// <reference types="vite/client" />
interface ImportMetaEnv {
readonly VITE_API_BASE_URL: string
readonly VITE_ENABLE_MOCK: string
}
interface ImportMeta {
readonly env: ImportMetaEnv
}小结
本章我们学习了 Vite 的环境变量与模式管理:
- Vite 内置变量:
import.meta.env.MODE / DEV / PROD - .env 文件:以
VITE_开头的变量可在客户端访问 - define 配置:手动注入变量到客户端
- 模式与命令行:
--mode参数切换环境 - 多环境实战:开发 / 测试 / 预发 / 生产
下一章我们将学习 静态资源处理。
至此,本章节的学习就到此结束了,如有疑惑,可对接技术客服进行相关咨询。