Vite仅按指定mode加载对应.env文件且遵循严格优先级。需在启动命令中显式使用--mode参数,如vite --mode development;修改.env后须重启服务或重新构建;非VITE_开头变量不会注入import.meta.env。

Vite 不会“自动加载所有 .env 文件”,它只按 mode 加载匹配的一组文件,并严格遵循优先级覆盖规则。你写再多 .env.xxx,不指定 mode 或文件名不规范,就根本不会被读。
怎么让 Vite 加载 .env.development 而不是 .env.production?
关键在启动命令里显式传入 --mode 参数,而不是依赖默认行为。
-
vite --mode development→ 加载.env.development和.env(后者被前者同名变量覆盖) -
vite build --mode staging→ 加载.env.staging和.env,.env.staging里的变量优先 -
vite build(无 mode)→ 默认 mode 是production,所以只加载.env.production和.env - package.json 里的 script 必须带
--mode xxx,光写vite build就永远走production
为什么改了 .env 但 import.meta.env 里还是旧值?
因为 Vite 在启动或构建时只读一次环境变量,之后不会监听文件变化。开发服务器运行中改 .env,必须重启 vite 进程才生效;build 产物里的值,是构建那一刻确定的,改完再跑 vite build 才会更新。
- 本地开发时,
.env.local和.env.development.local会被加载,且优先级最高 —— 适合存你个人的 token、调试开关 - 同名变量在多个文件里出现时,加载顺序决定谁胜出:
.env.[mode].local>.env.[mode]>.env.local>.env - 如果
.env.development里写了VITE_API_BASE=https://dev.api.com,但.env里也写了同名变量,.env.development的值会生效,.env的那行等于没写
如何让不同环境打包到不同 dist 目录?
靠 build.outDir 动态取值,但注意:它是在 Node.js 环境下执行的,不能用 import.meta.env(那是浏览器端的),得用 loadEnv 提前读取。
import { defineConfig, loadEnv } from 'vite'
export default defineConfig(({ command, mode }) => {
const env = loadEnv(mode, process.cwd(), '')
return {
build: {
outDir: `dist-${env.VITE_ENV_NAME || mode}`
}
}
})
-
loadEnv(mode, root, prefix)第三个参数设为空字符串,才能读到非VITE_开头的变量(比如你想用ENV_NAME=staging控制目录名) - 不要在
vite.config.ts顶层直接写import.meta.env.VITE_XXX,它此时还没注入,会是undefined -
outDir是路径字符串,不能含空格或非法字符,建议用短小清晰的命名如dist-staging
最常被忽略的一点:.env 文件里的变量,只要没加 VITE_ 前缀,就进不了 import.meta.env,哪怕你用 loadEnv 读到了,也仅限配置文件内部使用。想让前端代码感知到某个开关,必须以 VITE_ 开头,这是硬性边界,绕不开。


















