Skip to content

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 函数。这种方法:

  1. 官方支持:遵循 Vite 的设计理念
  2. 模式感知:能够根据构建模式自动加载对应的环境文件
  3. 安全可靠:只暴露必要的环境变量
  4. 灵活配置:支持自定义环境文件位置和变量前缀

避免直接使用 dotenv 或其他第三方库,除非你有特殊的需求,因为 Vite 已经提供了完整的环境变量解决方案。

环境文件加载优先级

Vite 会按以下顺序加载环境文件:

  1. .env.${mode}.local (仅本地,最高优先级)
  2. .env.${mode} (对应模式)
  3. .env.local (仅本地)
  4. .env (最低优先级)

通过正确使用环境变量,你可以轻松管理不同环境的配置,提高项目的可维护性和部署灵活性。