Vite 环境变量在 vite.config.js 中的使用
问题描述
在 Vite 项目中,我们经常需要在 .env 文件中定义环境变量:
sh
# 只有以 VITE_ 为前缀的变量才会暴露给 Vite 处理的代码
VITE_NAME=Wheatgrass
VITE_PORT=8080但如何在 vite.config.js 配置文件中访问这些环境变量呢?特别是在需要根据环境变量动态配置服务器端口或其他设置时,这个问题变得尤为重要。
环境变量前缀说明
Vite 默认只暴露以 VITE_ 为前缀的环境变量给客户端代码,这是为了防止意外泄露敏感信息。
解决方案
方法一:使用 Vite 内置的 loadEnv 函数(推荐)
这是 Vite 官方推荐的方法,也是最标准的解决方案:
javascript
import { defineConfig, loadEnv } from 'vite';
export default defineConfig(({ mode }) => {
// 加载环境变量
const env = loadEnv(mode, process.cwd());
return {
server: {
port: env.VITE_PORT ? parseInt(env.VITE_PORT) : 3000,
},
// 其他配置...
};
});参数说明
mode: 当前模式(development、production 或自定义模式)envDir: 环境文件目录,通常是process.cwd()(当前工作目录)prefixes: 要加载的变量前缀,默认为['VITE_']
方法二:处理特殊前缀的环境变量
如果你的项目需要处理非 VITE_ 前缀的环境变量(如从 Create React App 迁移的项目):
javascript
import { defineConfig, loadEnv } from 'vite';
export default defineConfig(({ mode }) => {
// 加载所有环境变量(包括非 VITE_ 前缀的)
const env = loadEnv(mode, process.cwd(), '');
return {
define: {
'process.env': Object.entries(env).reduce((prev, [key, val]) => {
return {
...prev,
[key]: val,
};
}, {}),
},
// 其他配置...
};
});方法三:处理自定义环境文件路径
如果环境文件不在项目根目录,需要指定正确路径:
javascript
import { defineConfig, loadEnv } from 'vite';
export default defineConfig(({ mode }) => {
const env = loadEnv(mode, "../", ""); // 环境文件在上级目录
return {
envDir: "../", // 同样需要指定环境文件目录
server: {
port: env.VITE_PORT,
},
};
});方法四:高级用法 - 多环境配置
对于复杂的多环境部署场景:
javascript
import { defineConfig, loadEnv } from 'vite';
import dotenv from 'dotenv';
import fs from 'fs';
export default defineConfig(({ mode }) => {
// 根据模式选择不同的环境文件
const envFile = mode === 'production' ? '.env.prod' : '.env.dev';
// 使用 dotenv 加载特定环境文件
if (fs.existsSync(envFile)) {
const envConfig = dotenv.parse(fs.readFileSync(envFile));
process.env = { ...process.env, ...envConfig };
}
return {
server: {
port: process.env.VITE_PORT || 3000,
},
};
});完整示例
以下是一个完整的 vite.config.js 配置示例:
javascript
import { defineConfig, loadEnv } from 'vite';
import vue from '@vitejs/plugin-vue';
export default defineConfig(({ mode }) => {
// 加载环境变量
const env = loadEnv(mode, process.cwd());
// 设置默认值
const API_URL = env.VITE_API_URL ?? 'http://localhost:3000';
const PORT = env.VITE_PORT ? parseInt(env.VITE_PORT) : 3000;
return {
plugins: [vue()],
server: {
port: PORT,
proxy: {
'/api': {
target: API_URL,
changeOrigin: true,
},
},
},
build: {
outDir: 'dist',
},
};
});常见问题解决
1. ESLint 报错 "process is not defined"
在 .eslintrc.cjs 中添加 node: true:
javascript
module.exports = {
env: {
browser: true,
es2020: true,
node: true // 添加这个配置
},
// 其他配置...
}2. 环境变量值为 undefined
注意事项
- 确保环境文件位于正确的位置(默认是项目根目录)
- 检查环境变量名称是否正确,包括大小写
- 确认运行命令的模式与期望加载的环境文件匹配
3. 类型提示支持
为了获得更好的 TypeScript 支持,可以创建 env.d.ts 文件:
typescript
/// <reference types="vite/client" />
interface ImportMetaEnv {
readonly VITE_PORT: string;
readonly VITE_API_URL: string;
// 更多环境变量...
}
interface ImportMeta {
readonly env: ImportMetaEnv;
}总结
在 Vite 配置文件中使用环境变量的最佳实践是使用 Vite 内置的 loadEnv 函数。这种方法:
- 官方支持:遵循 Vite 的设计理念
- 模式感知:能够根据构建模式自动加载对应的环境文件
- 安全可靠:只暴露必要的环境变量
- 灵活配置:支持自定义环境文件位置和变量前缀
避免直接使用 dotenv 或其他第三方库,除非你有特殊的需求,因为 Vite 已经提供了完整的环境变量解决方案。
环境文件加载优先级
Vite 会按以下顺序加载环境文件:
.env.${mode}.local(仅本地,最高优先级).env.${mode}(对应模式).env.local(仅本地).env(最低优先级)
通过正确使用环境变量,你可以轻松管理不同环境的配置,提高项目的可维护性和部署灵活性。