Vite 开发环境与生产环境配置完全指南

10 阅读7分钟

Vite 开发环境与生产环境配置指南

前言

在现代前端开发中,项目通常需要在不同的环境中运行:开发环境、测试环境、生产环境等。每个环境可能有不同的 API 地址、配置参数等。手动切换这些配置不仅繁琐,还容易出错。Vite 提供了完善的环境变量和模式管理机制,让我们可以优雅地管理不同环境的配置。

本文将详细介绍如何在 Vite 项目中配置开发环境和生产环境,包括环境变量的使用、代理配置、以及实际项目中的应用。

一、环境变量基础

1.1 Vite 环境变量机制

Vite 使用 import.meta.env 对象暴露环境变量,这些变量在构建时会被静态替换。Vite 提供了一些内建变量:

  • import.meta.env.MODE: 应用运行的模式(development/production)
  • import.meta.env.BASE_URL: 部署应用时的基本 URL
  • import.meta.env.PROD: 是否为生产环境(boolean)
  • import.meta.env.DEV: 是否为开发环境(boolean)
  • import.meta.env.SSR: 是否运行在服务端(boolean)

1.2 环境变量文件

Vite 使用 dotenv 从项目根目录加载环境变量文件,加载顺序如下:

.env                # 所有情况下都会加载
.env.local          # 所有情况下都会加载,但会被 git 忽略
.env.[mode]         # 只在指定模式下加载
.env.[mode].local   # 只在指定模式下加载,但会被 git 忽略

重要提示

  • 只有以 VITE_ 为前缀的变量才会暴露给客户端代码
  • 环境变量在 Vite 启动时加载,修改后需要重启服务器
  • .env.local 文件应该添加到 .gitignore 中,避免敏感信息泄露

二、项目配置实践

2.1 创建环境变量文件

在项目根目录创建以下环境变量文件:

.env.development - 开发环境配置
# 开发环境配置
NODE_ENV=development

# 开发服务器端口
VITE_PORT=8848

# 公共路径
VITE_PUBLIC_PATH=

# 路由历史模式
VITE_ROUTER_HISTORY=

# CDN配置
VITE_CDN=false

# 隐藏首页
VITE_HIDE_HOME=false

# 压缩配置
VITE_COMPRESSION=none

# API基础URL(开发环境使用代理,设置为 /api)
VITE_BASE_URL=/api

# 代理目标地址
VITE_TARGET=http://你的后端api地址
.env.production - 生产环境配置
# 生产环境配置
NODE_ENV=production

# 公共路径
VITE_PUBLIC_PATH=

# 路由历史模式
VITE_ROUTER_HISTORY=history

# CDN配置
VITE_CDN=false

# 压缩配置
VITE_COMPRESSION=gzip

# API基础URL(生产环境使用完整URL)
VITE_BASE_URL=https://api.example.com

# 生产环境不需要代理,但可以保留此变量
VITE_TARGET=https://api.example.com

2.2 配置 vite.config.ts

vite.config.ts 中读取环境变量并配置代理:

import { getPluginsList } from "./build/plugins";
import { include, exclude } from "./build/optimize";
import { type UserConfigExport, type ConfigEnv, loadEnv } from "vite";
import {
  root,
  alias,
  wrapperEnv,
  pathResolve,
  __APP_INFO__
} from "./build/utils";

export default ({ mode }: ConfigEnv): UserConfigExport => {
  // 加载环境变量
  const { VITE_CDN, VITE_PORT, VITE_COMPRESSION, VITE_PUBLIC_PATH } =
    wrapperEnv(loadEnv(mode, root));
  
  // 读取代理目标地址
  const config = loadEnv(mode, root);
  
  return {
    base: VITE_PUBLIC_PATH,
    root,
    resolve: {
      alias
    },
    server: {
      // 端口号
      port: VITE_PORT,
      host: "0.0.0.0",
      // 本地跨域代理(仅在开发环境生效)
      proxy: {
        "/api": {
          target: config.VITE_TARGET,
          changeOrigin: true,
          rewrite: path => path.replace(/^\/api/, "")
        }
      },
      cors: {
        origin: "*",
        credentials: true
      },
      // 预热文件以提前转换和缓存结果
      warmup: {
        clientFiles: ["./index.html", "./src/{views,components}/*"]
      }
    },
    plugins: getPluginsList(VITE_CDN, VITE_COMPRESSION),
    optimizeDeps: {
      include,
      exclude
    },
    build: {
      target: "es2015",
      sourcemap: false,
      chunkSizeWarningLimit: 4000,
      rollupOptions: {
        input: {
          index: pathResolve("./index.html", import.meta.url)
        },
        output: {
          chunkFileNames: "static/js/[name]-[hash].js",
          entryFileNames: "static/js/[name]-[hash].js",
          assetFileNames: "static/[ext]/[name]-[hash].[ext]"
        }
      }
    },
    define: {
      __INTLIFY_PROD_DEVTOOLS__: false,
      __APP_INFO__: JSON.stringify(__APP_INFO__)
    }
  };
};

关键点说明

  • loadEnv(mode, root) 会根据当前模式加载对应的环境变量文件
  • wrapperEnv() 函数用于处理环境变量,转换类型并设置默认值
  • 代理配置只在开发服务器中生效,生产环境构建后不会使用代理

2.3 配置 package.json 脚本

package.json 中配置不同环境的启动命令:

{
  "scripts": {
    "dev": "vite --mode development",//开发环境
    "serve": "pnpm dev",
    "build:test": "vite build --mode development",//测试(开发)环境打包
    "preview:test": "vite preview --mode development",//预览测试(开发)环境打的包
    "build": "vite build --mode production",//生产环境打包
    "start": "vite --mode production",//生产环境
    "build:staging": "rimraf dist && vite build --mode staging"
  }
}

命令说明

  • dev: 开发环境启动,自动加载 .env.development
  • build: 生产环境构建,自动加载 .env.production
  • build:test: 测试环境构建,使用 development 模式
  • build:staging: 预发布环境构建,需要创建 .env.staging 文件

2.4 在代码中使用环境变量

在 HTTP 请求中使用
// src/utils/http/index.ts
import Axios, { type AxiosInstance, type AxiosRequestConfig } from "axios";

// 从环境变量读取 API 基础URL
const baseURL = import.meta.env.VITE_BASE_URL;

const defaultConfig: AxiosRequestConfig = {
  timeout: 20000,
  baseURL: baseURL, // 开发环境: /api,生产环境: https://api.example.com
  headers: {
    Accept: "application/json, text/plain, */*",
    "Content-Type": "application/json",
    "X-Requested-With": "XMLHttpRequest"
  }
};

class PureHttp {
  private static axiosInstance: AxiosInstance = Axios.create(defaultConfig);
  // ... 其他代码
}

export const http = new PureHttp();
在组件中使用
// src/main.ts
import { createApp } from "vue";
import App from "./App.vue";

const app = createApp(App);

// 打印环境变量(仅用于调试)
console.log("环境变量", import.meta.env);
console.log("VITE_BASE_URL:", import.meta.env.VITE_BASE_URL);
console.log("VITE_TARGET:", import.meta.env.VITE_TARGET);
console.log("当前模式:", import.meta.env.MODE);
console.log("是否生产环境:", import.meta.env.PROD);

app.mount("#app");

三、代理配置详解

3.1 为什么需要代理?

在开发环境中,前端应用运行在 http://localhost:8848,而后端 API 可能运行在 http://x.x.xx.x:xxxx。直接请求会遇到 CORS(跨域资源共享)问题。

解决方案:使用 Vite 的代理功能,将 /api 开头的请求代理到后端服务器。

3.2 代理配置原理

proxy: {
  "/api": {
    target: "http://x.x.xx.x:xxxx",  // 后端服务器地址
    changeOrigin: true,                // 改变请求头中的 origin
    rewrite: path => path.replace(/^\/api/, "")  // 重写路径,去掉 /api 前缀
  }
}

工作流程

  1. 前端请求:http://localhost:8848/api/user/list
  2. Vite 代理转发:http://x.x.xx.x:xxxx/user/list
  3. 后端响应返回给前端

3.3 开发环境 vs 生产环境

环境API 请求方式配置
开发环境使用代理VITE_BASE_URL=/api + proxy.target
生产环境直接请求VITE_BASE_URL=https://api.example.com

开发环境

  • VITE_BASE_URL=/api → 请求走本地代理
  • 代理将请求转发到 VITE_TARGET 指定的后端服务器
  • 解决 CORS 问题

生产环境

  • VITE_BASE_URL=https://api.example.com → 直接请求生产 API
  • 不需要代理(代理只在开发服务器中生效)
  • 通常通过 Nginx 等服务器配置解决跨域

四、环境变量优先级

Vite 加载环境变量的优先级(从高到低):

  1. 命令行中的环境变量VITE_SOME_KEY=123 vite build
  2. 模式特定文件.env.[mode].local > .env.[mode]
  3. 通用文件.env.local > .env

例如,执行 vite build --mode production 时:

  1. 先加载 .env
  2. 再加载 .env.production(覆盖 .env 中的同名变量)
  3. 最后加载 .env.production.local(如果有,覆盖前面的)

五、最佳实践

5.1 环境变量命名规范

  • ✅ 使用 VITE_ 前缀(必须)
  • ✅ 使用大写字母和下划线
  • ✅ 语义化命名
# ✅ 正确
VITE_API_BASE_URL=https://api.example.com
VITE_APP_TITLE=我的应用

# ❌ 错误(不会暴露给客户端)
API_BASE_URL=https://api.example.com

5.2 敏感信息处理

  • 不要在环境变量中存储敏感信息(如密码、密钥)
  • ✅ 使用 .env.local 存储本地配置
  • ✅ 将 .env.local 添加到 .gitignore
# .gitignore
.env.local
.env*.local

5.3 多环境管理

对于大型项目,可以创建多个环境文件:

.env.development      # 开发环境
.env.test            # 测试环境
.env.staging         # 预发布环境
.env.production      # 生产环境

对应的启动命令:

{
  "scripts": {
    "dev": "vite --mode development",
    "build:test": "vite build --mode test",
    "build:staging": "vite build --mode staging",
    "build": "vite build --mode production"
  }
}

六、常见问题

Q1: 环境变量修改后不生效?

A: 环境变量在 Vite 启动时加载,修改后需要重启开发服务器(一定不要忘)。

Q2: 为什么 console.log(import.meta.env.VITE_XXX) 输出 undefined

A: 检查以下几点:

  • 变量名是否以 VITE_ 开头
  • 环境变量文件是否在项目根目录
  • 是否在正确的模式下运行(--mode development
  • 是否重启了服务器

Q3: 生产环境构建后代理不生效?

A: 代理只在开发服务器中生效。生产环境应该:

  • 配置 VITE_BASE_URL 为完整的生产 API 地址
  • 通过 Nginx 等服务器配置反向代理或 CORS

Q4: 如何在 HTML 中使用环境变量?

A: Vite 支持在 HTML 中使用 %ENV_NAME% 语法:

<title>%VITE_APP_TITLE%</title>
<p>API地址: %VITE_BASE_URL%</p>

七、总结

通过合理配置 Vite 的环境变量和代理,我们可以:

  1. 统一管理不同环境的配置
  2. 解决跨域问题(开发环境)
  3. 提高开发效率,无需手动切换配置
  4. 保证安全性,敏感信息不提交到代码库

希望本文能帮助你更好地管理 Vite 项目的环境配置。如有问题,欢迎交流讨论!

参考资源