Vite项目中打包环境变量教程
作者:像素行者
本文详细介绍了在Vite项目中配置和使用环境变量的完整流程,帮助开发者安全高效地管理不同环境下的应用配置,感兴趣的可以了解下
1. 环境变量基础概念
环境变量是在构建过程中注入应用程序的值,用于区分不同的运行环境(开发、测试、生产等)。在Vite中,环境变量通过 import.meta.env 对象在客户端代码中访问。
为什么需要环境变量?
- 区分开发、测试、生产环境的配置
- 隐藏敏感信息(API密钥、数据库连接等)
- 灵活调整应用行为而无需修改代码
- 实现不同环境的特定配置
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 时
- production - 运行 vite build 时
可以通过命令指定模式:
vite build --mode staging npm run build -- --mode test
3. 环境变量文件配置
3.1 基础配置示例
.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_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.js 中配置:
export default defineConfig({
envPrefix: 'APP_' // 暴露以 APP_ 开头的变量
})4. 在代码中访问环境变量
4.1 基本用法
// 在任何JavaScript/TypeScript文件中
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 // 是否开发环境 (boolean) import.meta.env.PROD // 是否生产环境 (boolean) import.meta.env.SSR // 是否SSR构建 (boolean) 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类型提示
env.d.ts
/// <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在构建时会进行静态字符串替换:
// 源代码 const apiUrl = import.meta.env.VITE_API_URL // 打包后(以production模式) const apiUrl = "https://api.example.com"
5.3 条件编译示例
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-shake移除
console.log('Development build')
}
6. 实战配置示例
6.1 多环境配置方案
.env
VITE_APP_TITLE=My Application VITE_VERSION=1.0.0
.env.development
VITE_API_BASE_URL=http://localhost:8000 VITE_API_TIMEOUT=30000 VITE_LOG_LEVEL=debug VITE_MOCK_API=true
.env.staging
VITE_API_BASE_URL=https://staging-api.example.com VITE_API_TIMEOUT=30000 VITE_LOG_LEVEL=info VITE_MOCK_API=false
.env.production
VITE_API_BASE_URL=https://api.example.com VITE_API_TIMEOUT=60000 VITE_LOG_LEVEL=error VITE_MOCK_API=false
.env.local(.gitignore中)
VITE_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客户端配置
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 => {
// Mock响应逻辑
return response
})
}
export default client6.4 Vite配置文件
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_开头 - 确保文件在项目根目录(与
package.json同级)
7.2 敏感信息泄露
问题:私有密钥被打包到生产代码中。
解决:
- 敏感信息放在
.env.local中(添加到.gitignore) - 使用
.env.[mode].local文件进行本地覆盖 - 不使用
VITE_前缀的变量不会被暴露 - 考虑在构建时从环境变量注入敏感信息
# 在CI/CD中注入 VITE_API_KEY=xxx npm run build
7.3 TypeScript提示不准确
问题:import.meta.env.VITE_* 没有类型提示。
解决:创建 env.d.ts 文件定义类型(见第4.4节)
7.4 变量在条件语句中不工作
问题:使用变量值进行条件判断时,分支没有被tree-shake。
解决:使用内置变量(如 import.meta.env.PROD)进行条件判断,而非自定义变量值
// ✅ 会被正确tree-shake
if (import.meta.env.PROD) { ... }
// ❌ 可能不会被tree-shake
if (import.meta.env.VITE_ENABLE_FEATURE === 'true') { ... }
8. 最佳实践
- 明确的命名约定:使用
VITE_前缀,使用下划线分隔单词 - 分离配置文件:创建专门的配置模块来管理环境变量
- 类型安全:为TypeScript项目编写
env.d.ts - 安全性:敏感信息使用
.local文件,添加到.gitignore - 文档化:在README或wiki中说明所有可用的环境变量及其含义
- 验证:在应用启动时验证必要的环境变量是否存在
- CI/CD集成:在构建流程中动态注入环境变量
9. 快速参考
# 开发环境运行 npm run dev # 使用.env和.env.development # 生产环境构建 npm run build # 使用.env和.env.production # 自定义模式构建 npm run build -- --mode staging # 列出当前所有加载的环境变量(Vite 3.1+) # 在vite.config.js中使用loadEnv() // 快速访问 import.meta.env.MODE // 当前模式 import.meta.env.DEV // 开发环境 import.meta.env.PROD // 生产环境 import.meta.env.VITE_* // 自定义变量
到此这篇关于Vite项目中打包环境变量教程的文章就介绍到这了,更多相关Vite 打包环境变量内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
