1. 环境变量的基本理解
环境变量是在构建阶段注入到项目中的配置值,主要用于区分不同运行环境(如开发、测试、生产)的行为。在 Vite 构建工具中,这些变量可以通过 import.meta.env 对象在前端代码中直接读取。
为何要使用环境变量?
- 实现多环境(开发/测试/生产)的差异化配置
- 保护敏感信息,例如 API 密钥或数据库连接字符串
- 无需修改源码即可动态调整应用行为
- 支持特定环境下的功能开关与调试设置
import.meta.env
2. Vite 中环境变量的运行机制
2.1 文件命名与加载规则
Vite 通过预定义的文件名来识别和加载对应的环境配置文件,遵循一定的优先级顺序进行合并与覆盖。
.env # 所有环境下都会加载
.env.local # 所有环境下都会加载(本地覆盖,.gitignore中)
.env.[mode] # 特定模式下加载(如.env.production)
.env.[mode].local # 特定模式下加载(本地覆盖)
加载顺序说明(后加载的会覆盖前面的内容):
.env
.env.local
.env.[mode]
.env.[mode].local
2.2 模式的定义与使用
“模式”代表不同的构建上下文环境。Vite 默认提供两种主要模式:
development
- 执行
vite命令时,默认进入 development 模式
vite
production
vite build 时,则默认为 production 模式vite build
也可以通过命令行手动指定模式:
vite build --mode staging
npm run build -- --mode test
3. 配置环境变量文件
3.1 配置文件示例
项目根目录下可创建多个以 .env 开头的配置文件,用于管理不同环境的变量。
.env(通用环境变量)
VITE_APP_TITLE=My App
VITE_BASE_URL=http://localhost:3000
.env.production(生产环境专用)
VITE_APP_TITLE=My App Pro
VITE_BASE_URL=https://api.example.com
.env.development(开发环境专用)
VITE_APP_TITLE=My App Dev
VITE_BASE_URL=http://localhost:5173
.env.local(本地私有配置,不应提交至版本控制系统)
VITE_SECRET_KEY=xxx-secret-key-xxx
3.2 变量命名规范
出于安全考虑,只有以特定前缀开头的变量才会被暴露给客户端代码。
VITE_
例如,默认情况下仅 VITE_ 开头的变量可在浏览器端访问:
? 正确:
VITE_API_URL=https://api.example.com
VITE_APP_NAME=MyApp
VITE_MAX_UPLOAD_SIZE=10485760
? 错误(不会被暴露):
API_URL=https://api.example.com
SECRET_KEY=secret-value
若需自定义暴露前缀,可在 vite.config.ts 中进行设置:
vite.config.js
export default defineConfig({
envPrefix: 'APP_' // 只暴露以 APP_ 开头的变量
})
4. 在代码中调用环境变量
4.1 基础使用方式
在任意 JavaScript 或 TypeScript 文件中均可通过 import.meta.env 获取配置值:
// 输出 API 地址和应用标题
console.log(import.meta.env.VITE_API_URL)
console.log(import.meta.env.VITE_APP_TITLE)
// 根据环境执行不同逻辑
if (import.meta.env.PROD) {
// 生产环境专属操作
}
if (import.meta.env.DEV) {
// 开发环境处理逻辑
}
4.2 内建环境变量说明
Vite 提供了一些内置的环境标识,便于判断当前构建状态:
import.meta.env.MODE—— 当前模式名称(如 development、production)import.meta.env.DEV—— 是否处于开发模式(布尔值)import.meta.env.PROD—— 是否为生产构建(布尔值)import.meta.env.SSR—— 是否为服务端渲染构建import.meta.env.BASE_URL—— 应用部署的基础路径
4.3 封装环境变量工具类
为了提升可维护性,建议将环境变量集中封装成一个配置模块:
// src/config/env.js
export const env = {
apiUrl: import.meta.env.VITE_API_URL,
appTitle: import.meta.env.VITE_APP_TITLE,
isDev: import.meta.env.DEV,
isProd: import.meta.env.PROD,
}
使用时只需导入即可:
import { env } from '@/config/env'
console.log(env.apiUrl)
4.4 支持 TypeScript 类型提示
为了让编辑器正确识别自定义环境变量类型,可在项目中添加类型声明文件:
/// <reference types="vite/client" />
interface ImportMetaEnv {
readonly VITE_API_URL: string
readonly VITE_APP_TITLE: string
readonly VITE_MAX_UPLOAD_SIZE: string
}
interface ImportMeta {
readonly env: ImportMetaEnv
}
5. 构建打包过程中的处理策略
5.1 打包命令详解
执行构建任务时可根据需要选择不同模式:
# 默认以 production 模式构建
npm run build
vite build
# 使用自定义模式构建
vite build --mode staging
vite build --mode development
# 预览最终构建结果
npm run preview
5.2 构建时的静态替换机制
Vite 在打包过程中会对 import.meta.env 进行静态分析,并将对应值直接替换为字面量。
示例:
// 源码中
const apiUrl = import.meta.env.VITE_API_URL
// 构建后(假设为 production 模式)
const apiUrl = "https://api.example.com"
这种替换是编译期完成的,不会暴露未使用的变量。
5.3 条件编译的实际应用
利用环境标志可以实现代码级别的条件编译,控制某些代码块是否被打包进最终产物:
if (import.meta.env.PROD) {
// 此段代码仅在生产环境中保留
}
if (import.meta.env.PROD) {
console.log('Production build')
} else if (import.meta.env.DEV) {
// 开发环境代码
console.log('Development build')
}
// 打包后(production模式)
if (true) {
// 这个分支会被保留
console.log('Production build')
} else if (false) {
// 这个分支将被Tree-shaking移除
console.log('Development build')
}
6. 实战配置示例
6.1 多环境变量配置方案
通过不同命名的 .env 文件实现多环境隔离,每个文件对应特定运行环境:
- .env —— 默认环境配置
- .env.development —— 开发环境
- .env.staging —— 预发布环境
- .env.production —— 生产环境
- .env.local —— 本地覆盖配置(通常被 .gitignore 忽略)
VITE_APP_TITLE=My Application
VITE_VERSION=1.0.0VITE_API_BASE_URL=http://localhost:8000
VITE_API_TIMEOUT=30000
VITE_LOG_LEVEL=debug
VITE_MOCK_API=trueVITE_API_BASE_URL=https://staging-api.example.com
VITE_API_TIMEOUT=30000
VITE_LOG_LEVEL=info
VITE_MOCK_API=falseVITE_API_BASE_URL=https://api.example.com
VITE_API_TIMEOUT=60000
VITE_LOG_LEVEL=error
VITE_MOCK_API=falseVITE_SECRET_TOKEN=abc123xyz
6.2 应用级统一配置管理
集中化读取环境变量,便于全局调用和维护。以下为配置入口文件示例:
src/config/index.js
export default {
appTitle: import.meta.env.VITE_APP_TITLE,
version: import.meta.env.VITE_VERSION,
api: {
baseURL: import.meta.env.VITE_API_BASE_URL,
timeout: parseInt(import.meta.env.VITE_API_TIMEOUT),
},
logger: {
level: import.meta.env.VITE_LOG_LEVEL,
},
mockApi: import.meta.env.VITE_MOCK_API === 'true',
isDev: import.meta.env.DEV,
isProd: import.meta.env.PROD,
}
6.3 API 客户端初始化设置
基于 axios 封装请求客户端,并根据配置动态启用模拟数据拦截逻辑:
src/api/client.js
import axios from 'axios'
import config from '@/config'
const client = axios.create({
baseURL: config.api.baseURL,
timeout: config.api.timeout,
})
// 根据配置决定是否添加 mock 响应拦截器
if (config.mockApi) {
client.interceptors.response.use(response => {
// 模拟接口响应处理逻辑
return response
})
}
export default client
6.4 Vite 构建工具配置详解
结合 loadEnv 方法动态加载对应环境变量,灵活适配多种部署场景:
vite.config.js
import { defineConfig, loadEnv } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'
export default defineConfig(({ command, mode }) => {
// 加载当前模式下的所有环境变量
const env = loadEnv(mode, process.cwd(), '')
return {
plugins: [vue()],
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),
},
},
server: {
port: 5173,
proxy: {
'/api': {
target: env.VITE_API_BASE_URL,
changeOrigin: true,
rewrite: path => path.replace(/^\/api/, ''),
},
},
},
envPrefix: 'VITE_',
define: {
__APP_VERSION__: JSON.stringify(env.npm_package_version),
},
}
})
7. 常见问题与应对策略
7.1 环境变量未生效
现象描述:修改了 .env 文件后,应用中未能获取更新后的值。
解决方案:
- 重启开发服务器(Vite 在启动时一次性加载环境变量)
- 确认变量名称以 VITE_ 开头,否则不会暴露给客户端代码
- 确保 .env 文件位于项目根目录,与 package.json 同级
.envviteVITE_package.json
7.2 敏感信息意外泄露风险
现象描述:私钥等敏感内容被误打包进前端生产构建产物中。
解决方案:
- 将敏感信息存储于 .env.private 或类似非公开文件中,并加入 .gitignore
- 使用 .env.local 文件进行本地开发覆盖,避免提交到版本控制
- 不使用 VITE_ 前缀的变量不会被注入到客户端,可用于存放后端专用配置
- 在 CI/CD 流程中通过环境变量传入关键密钥,例如:
# 在持续集成环境中注入并构建
VITE_API_KEY=xxx npm run build
.env.local.gitignore.env.[mode].localVITE_
7.3 TypeScript 类型提示缺失
现象描述:使用 import.meta.env 时缺乏自动补全与类型检查支持。
解决方案:创建自定义类型声明文件以增强类型系统识别能力:
- 新建 env.d.ts 或在现有声明文件中扩展 ImportMetaEnv 接口
- 参考第4.4节完成类型定义配置
import.meta.env.VITE_*env.d.ts
7.4 条件判断中环境变量失效
现象描述:在 if/else 分支中使用环境变量时,无法正确触发静态分析优化。
说明:Vite 使用编译时替换机制,仅当表达式为字面量常量(如 true/false)时才能进行 tree-shaking。若依赖运行时变量,则无法移除死代码。
建议做法:确保条件语句中的判断依据是编译时可解析的常量表达式,以便构建工具能准确剔除无用代码块。
在进行条件判断时,若使用变量值控制代码分支,可能会导致无法被正确地 tree-shake(摇树优化),从而使得未使用的代码仍保留在最终打包结果中。
解决方案:推荐使用内置的环境标识变量(如 import.meta.env.PROD)来进行条件判断,而不是依赖自定义的环境变量值。因为构建工具(如 Vite)能够静态分析这些内置变量,并在编译阶段移除不可达的代码分支。
// 会被正确 tree-shake
if (import.meta.env.PROD) {
// 只在生产环境中执行的逻辑
}
// 可能不会被 tree-shake
if (import.meta.env.VITE_ENABLE_FEATURE === 'true') {
// 即使值为 false,该块也可能未被移除
}
import.meta.env.PROD
8. 最佳实践
-
命名规范清晰:所有自定义环境变量应以
VITE_前缀开头,并使用下划线分隔单词,确保可读性和一致性。VITE_ - 配置文件分离:创建独立的配置模块来集中管理不同环境下的变量,提升可维护性。
-
类型安全保障:对于 TypeScript 项目,建议定义精确的类型接口,为
import.meta.env提供自动补全和类型检查支持。env.d.ts -
敏感信息保护:将涉及安全的密钥或凭证存放在专用的
.env文件中,并通过.gitignore排除版本控制,防止泄露。.local.gitignore - 文档说明完整:在项目的 README 或内部 Wiki 中详细列出所有可用的环境变量及其用途、默认值和示例。
- 启动时校验:在应用初始化阶段验证关键环境变量是否存在且格式正确,避免运行时错误。
- 与 CI/CD 流程集成:在持续集成与部署流程中动态注入环境相关的变量,实现多环境自动化构建。
9. 快速参考指南
# 启动开发服务器(加载 .env 和 .env.development)
npm run dev
# 构建生产版本(加载 .env 和 .env.production)
npm run build
# 使用自定义模式构建(例如 staging 环境)
npm run build -- --mode staging
从 Vite 3.1 开始,可通过 loadEnv() 函数获取当前已加载的所有环境变量。
// 快速访问常用环境属性
import.meta.env.MODE // 当前运行模式(如:development, production, staging)
import.meta.env.DEV // 是否处于开发环境(boolean)
import.meta.env.PROD // 是否处于生产环境(boolean)
import.meta.env.VITE_* // 所有以 VITE_ 开头的自定义变量

雷达卡


京公网安备 11010802022788号







