Vite 环境变量配置经验总结

目录

  1. 快速开始
  2. 核心概念
  3. 环境变量文件系统
  4. 命令与环境对应
  5. 最佳实践
  6. 常见问题
  7. 扩展:其他加载方式

快速开始

三步上手

第一步:创建 .env 文件

bash 复制代码
# .env.development
VITE_API_URL=http://localhost:3000

# .env.production
VITE_API_URL=https://api.example.com

第二步:在代码中访问

typescript 复制代码
// 任意 .vue、.tsx、.js 文件中
const apiUrl = import.meta.env.VITE_API_URL;
console.log(apiUrl); // 开发环境输出: http://localhost:3000

第三步:运行项目

bash 复制代码
npm run dev    # 自动加载 .env.development
npm run build  # 自动加载 .env.production

核心要点

  • ✅ 变量名必须以 VITE_ 开头
  • ✅ 修改 .env 文件后需重启开发服务器
  • ✅ 使用 import.meta.env.变量名 访问

核心概念

Vite 环境变量的工作原理

Vite 在构建时会读取 .env 文件,并将环境变量注入到你的应用中。

关键特性:

  1. 前缀限制 :只有以 VITE_ 开头的变量才会暴露给客户端代码
  2. 构建时注入:环境变量在构建时就已经被静态替换到代码中
  3. 模式驱动 :通过 mode 参数决定加载哪个 .env.[mode] 文件

为什么需要 VITE_ 前缀?

这是一个安全机制,防止敏感信息(如数据库密码、API 密钥)意外暴露到客户端代码中。

bash 复制代码
# ✅ 会暴露给客户端
VITE_API_URL=https://api.example.com

# ❌ 不会暴露给客户端(仅在 vite.config.ts 中可用)
DATABASE_PASSWORD=secret123
API_SECRET_KEY=xyz789

两种访问方式

客户端代码(浏览器):

typescript 复制代码
// 只能访问 VITE_ 开头的变量
const apiUrl = import.meta.env.VITE_API_URL;
const mode = import.meta.env.MODE;
const isDev = import.meta.env.DEV;

配置文件(Node.js):

typescript 复制代码
// vite.config.ts - 可以访问所有变量
import { defineConfig, loadEnv } from 'vite';

export default defineConfig(({ mode }) => {
  const env = loadEnv(mode, process.cwd(), '');
  console.log(env.VITE_API_URL);      // ✅ 可以访问
  console.log(env.DATABASE_PASSWORD);  // ✅ 也可以访问
  return { /* ... */ };
});

环境变量文件系统

文件命名规则

Vite 支持以下环境变量文件(按优先级从低到高):

bash 复制代码
1. .env                    # 所有环境都会加载(最低优先级)
2. .env.local              # 所有环境都会加载,但会被 git 忽略
3. .env.[mode]             # 只在指定 mode 时加载
4. .env.[mode].local       # 只在指定 mode 时加载,但会被 git 忽略(最高优先级)

加载顺序

后加载的文件会覆盖前面加载的文件中相同的变量

示例:运行 vite --mode development

markdown 复制代码
1. .env                    → 加载(基础配置)
2. .env.local              → 加载(本地覆盖,如果存在)
3. .env.development        → 加载(开发环境配置)
4. .env.development.local  → 加载(开发环境本地覆盖,如果存在,最高优先级)

文件优先级表

优先级 文件名 何时加载 Git 状态 用途
1(最低) .env 所有模式 通常提交 公共配置
2 .env.local 所有模式 不提交 本地公共覆盖
3 .env.[mode] 指定 mode 通常提交 环境特定配置
4(最高) .env.[mode].local 指定 mode 不提交 环境特定本地覆盖
- .env.example 从不加载 提交 仅作示例模板

.env.example 说明

.env.example 文件不会被 Vite 自动读取,它只是一个示例模板文件,用于:

  • 告诉开发者需要配置哪些环境变量
  • 作为文档说明
  • 通常提交到 Git 仓库
  • 开发者可以复制它来创建实际的 .env 文件

命令与环境对应

默认命令行为

命令 NODE_ENV mode 读取的 .env 文件
vite development development .env.env.local.env.development.env.development.local
vite build production production .env.env.local.env.production.env.production.local
vite preview production production 不读取(使用构建时的值)
vitest test test .env.env.local.env.test.env.test.local

补充说明 1:vite preview 不读取环境变量

vite preview 不会读取新的 .env 文件,原因:

  • vite preview 只是预览已经构建好的 dist 目录
  • 环境变量在 vite build 时就已经注入到代码中
  • preview 阶段不会重新构建,所以不会重新读取 .env

如果需要不同的预览环境,需要在构建时指定不同的 --mode

bash 复制代码
# 构建时使用不同的 mode
vite build --mode staging
vite preview

补充说明 2:NODE_ENV vs mode

细心的读者会注意到,上面的表格中有 NODE_ENVmode 两列,它们是两个独立的概念,容易混淆:

process.env.NODE_ENV

  • Node.js 环境变量,控制构建优化(代码压缩、tree-shaking)
  • 由 Vite 根据命令自动设置:vitedevelopmentvite buildproduction
  • vite.config.ts 中通过 process.env.NODE_ENV 访问

mode(模式)

  • Vite 的模式参数,决定加载哪个 .env.[mode] 文件
  • 可以是任意自定义值(如 stagingtest
  • 通过 --mode 参数指定,在客户端通过 import.meta.env.MODE 访问

关键区别:

命令 NODE_ENV mode 说明
vite development development 默认相同
vite build production production 默认相同
vite build --mode staging production staging 可以不同 ⚠️
NODE_ENV=test vite build test production 可以不同 ⚠️

💡 推荐做法 :在 Vite 项目中,优先使用 import.meta.env.MODE 来判断环境,而不是依赖 process.env.NODE_ENV


最佳实践

1. 完整的文件结构

bash 复制代码
project/
├── .env                    # 所有环境的公共配置(提交)
├── .env.development        # 开发环境配置(提交)
├── .env.production         # 生产环境配置(提交)
├── .env.local             # 本地覆盖配置(不提交)
├── .env.example           # 示例模板(提交)
└── .gitignore             # 添加 .env*.local

示例内容:

bash 复制代码
# .env - 公共配置
VITE_APP_NAME=My App

# .env.development
VITE_API_URL=http://localhost:3000
VITE_DEBUG=true

# .env.production
VITE_API_URL=https://api.example.com
VITE_DEBUG=false

# .env.example - 示例模板
VITE_API_URL=
VITE_APP_NAME=

2. 命名规范

bash 复制代码
# ✅ 正确写法
VITE_API_BASE_URL=https://api.example.com
VITE_APP_TITLE=My App
VITE_ENABLE_MOCK=true

# ❌ 错误写法(客户端无法访问)
API_BASE_URL=https://api.example.com
appTitle=My App

规则:

  • 必须以 VITE_ 开头
  • 使用全大写字母
  • 单词间用下划线分隔

3. 客户端代码使用

typescript 复制代码
// 访问环境变量
const apiUrl = import.meta.env.VITE_API_URL;

// 内置变量
const mode = import.meta.env.MODE;       // 当前模式
const isDev = import.meta.env.DEV;       // 是否开发环境
const isProd = import.meta.env.PROD;     // 是否生产环境
const baseUrl = import.meta.env.BASE_URL; // 公共基础路径

// 带默认值
const debug = import.meta.env.VITE_DEBUG || 'false';

4. 在 vite.config.ts 中使用

typescript 复制代码
import { defineConfig, loadEnv } from 'vite';

export default defineConfig(({ mode }) => {
  // 加载环境变量
  const env = loadEnv(mode, process.cwd(), '');
  
  return {
    // 方式1: 使用 define 注入全局常量
    define: {
      __APP_VERSION__: JSON.stringify('1.0.0'),
      __API_URL__: JSON.stringify(env.VITE_API_URL),
    },
  
    // 方式2: 根据环境变量配置插件
    server: {
      port: Number(env.VITE_PORT) || 3000,
      proxy: env.VITE_API_URL ? {
        '/api': {
          target: env.VITE_API_URL,
          changeOrigin: true,
        }
      } : undefined,
    },
  };
});

5. TypeScript 类型支持

创建 env.d.ts 为环境变量添加类型:

typescript 复制代码
/// <reference types="vite/client" />

interface ImportMetaEnv {
  readonly VITE_API_URL: string;
  readonly VITE_APP_NAME: string;
  readonly VITE_DEBUG: string;
}

interface ImportMeta {
  readonly env: ImportMetaEnv;
}

常见问题

Q: 为什么我的环境变量在客户端访问不到? A: 确保变量名以 VITE_ 开头,并且重新启动开发服务器。

Q: 如何在不同环境使用不同的配置? A: 创建 .env.development.env.production 等文件,或使用 --mode 参数。

Q: vite preview 能读取新的环境变量吗? A: 不能,环境变量在构建时就已经注入,需要重新构建才能更新。

Q: .env.example 会被 Vite 加载吗? A: 不会,它只是示例模板,需要复制为实际的 .env 文件。


扩展:其他加载方式

在非 Vite 项目或 Node.js 脚本中,你可能需要其他方式加载环境变量。

方式对比

方式 适用场景 使用方法 说明
Vite 内置 Vite 项目 自动加载,无需配置 ✅ 推荐
dotenv 库 Node.js 脚本 require('dotenv').config() 需要安装依赖
Node.js 原生 Node.js 20.6+ node --env-file=.env app.js 无需依赖,原生支持
tsx TypeScript 文件 tsx --env-file=.env app.ts 直接运行 .ts 文件

dotenv 库使用

bash 复制代码
npm install dotenv
typescript 复制代码
// 基本用法
import dotenv from 'dotenv';
dotenv.config();

// 指定文件
dotenv.config({ path: '.env.development' });

// 访问变量
console.log(process.env.DB_HOST);

Node.js 原生支持(20.6+)

bash 复制代码
# 命令行使用
node --env-file=.env app.js

# package.json
{
  "scripts": {
    "dev": "node --env-file=.env.development src/index.js"
  }
}

TypeScript 类型声明

typescript 复制代码
// env.d.ts
declare global {
  namespace NodeJS {
    interface ProcessEnv {
      DB_HOST: string;
      API_KEY: string;
    }
  }
}

export {};

适用版本:Vite 5.x+, Node.js 20.6+

相关推荐
咪库咪库咪41 分钟前
vue5
前端
前端缘梦41 分钟前
JavaScript核心机制:执行栈、作用域与this指向完全解析
前端·javascript·面试
Larry_zhang双栖41 分钟前
解决 Figma MCP 下载图片卡死问题:从踩坑到自研 npm 工具全记录
前端·npm·figma
JarvanMo42 分钟前
Flutter 3.38 动画新特性:动画引擎有什么新变化?
前端
ByteCraze1 小时前
CDN 引入 与 npm 引入的区别
前端·npm·node.js
Youyzq1 小时前
react 元素触底hooks封装
前端·javascript·react.js
crary,记忆1 小时前
PNPM 和 NPM
前端·学习·npm·node.js
爱吃无爪鱼1 小时前
04-npm 与 Bun 快速入门实战指南
前端·vue.js·react.js·npm·sass
灵犀坠1 小时前
前端面试&项目实战核心知识点总结(Vue3+Pinia+UniApp+Axios)
前端·javascript·css·面试·职场和发展·uni-app·html