Become a sponsor

概述
本节说明前端项目的环境变量配置和 Vite 构建配置,包括开发环境和生产环境的差异配置。前端通过 .env 文件管理环境变量,Vite 自动根据模式加载对应的 .env 文件。
ui/
├── .env # 所有环境通用配置
├── .env.development # 开发环境配置
├── .env.production # 生产环境配置
└── .env.local # 本地覆盖(不提交 git)加载优先级: .env.local > .env.{mode} > .env
.env.development # 开发服务器端口
VITE_PORT = 8001
# 公共基础路径(通常为 /)
VITE_PUBLIC_PATH = /
# API 接口基础路径(留空,由代理处理)
VITE_GLOB_API_URL =
# API 前缀(所有接口路径的前缀)
VITE_GLOB_API_URL_PREFIX = /api
# 代理配置(JSON 数组格式:[["前缀","目标地址"]])
VITE_PROXY = [["/api","http://admin.thinkphp6.elevue/api"]]
# 上传接口地址
VITE_GLOB_UPLOAD_URL = /api/upload
# 图片访问地址(用于预览上传的图片)
VITE_GLOB_IMG_URL = http://file.thinkphp6.elevue
# 是否在生产环境删除 console(开发环境保留)
VITE_DROP_CONSOLE = false
# 是否启用 Mock 数据(false = 使用真实后端 API)
VITE_USE_MOCK = false.env.production # 公共基础路径(通常为 /,如部署到子目录则设为 /subdir/)
VITE_PUBLIC_PATH = /
# API 接口基础路径(留空,由 Nginx 代理处理)
VITE_GLOB_API_URL =
# API 前缀
VITE_GLOB_API_URL_PREFIX = /api
# 上传接口地址
VITE_GLOB_UPLOAD_URL = /api/upload
# 图片访问地址(生产环境使用正式域名)
VITE_GLOB_IMG_URL = https://cdn.example.com
# 是否在生产环境删除 console
VITE_DROP_CONSOLE = true
# 是否启用 gzip 压缩
VITE_BUILD_COMPRESS = gzip
# 压缩后是否删除原文件
VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE = falseVITE_PORT = 8001| 环境 | 值 | 说明 |
|---|---|---|
| 开发 | 8001 | 前端开发服务器端口 |
| 生产 | 不生效 | 生产环境由 Nginx 提供服务 |
VITE_PUBLIC_PATH = /| 场景 | 值 | 说明 |
|---|---|---|
| 根目录部署 | / | 默认值 |
| 子目录部署 | /admin/ | 如 https://example.com/admin/ |
VITE_GLOB_API_URL =| 场景 | 值 | 说明 |
|---|---|---|
| 开发(代理) | 留空 | 由 Vite proxy 转发 |
| 生产(同域) | 留空 | 由 Nginx 代理 |
| 生产(跨域) | https://api.example.com | 直接请求后端域名 |
VITE_PROXY = [["/api","http://admin.thinkphp6.elevue/api"]]格式: JSON 数组,每项为 [前缀, 目标地址]
作用: 将前端 /api/* 请求代理到后端地址,解决开发环境跨域问题。
多代理示例:
VITE_PROXY = [["/api","http://localhost:8080/api"],["/upload","http://localhost:8080/upload"]]VITE_GLOB_API_URL_PREFIX = /api所有 API 请求路径的前缀,与后端路由前缀一致。
VITE_GLOB_UPLOAD_URL = /api/upload文件上传组件使用的接口地址。
# 开发环境
VITE_GLOB_IMG_URL = http://file.thinkphp6.elevue
# 生产环境
VITE_GLOB_IMG_URL = https://cdn.example.com用于预览上传的图片,拼接图片的完整 URL。
# 开发环境:保留 console(方便调试)
VITE_DROP_CONSOLE = false
# 生产环境:删除 console(安全+减小体积)
VITE_DROP_CONSOLE = trueVITE_BUILD_COMPRESS = gzip启用 gzip 压缩后,构建产物会生成 .gz 文件,Nginx 配置 gzip_static on 可直接使用。
// 读取环境变量(VITE_ 前缀的变量才会暴露给客户端)
const apiUrl = import.meta.env.VITE_GLOB_API_URL;
const apiPrefix = import.meta.env.VITE_GLOB_API_URL_PREFIX;
const uploadUrl = import.meta.env.VITE_GLOB_UPLOAD_URL;
const imgUrl = import.meta.env.VITE_GLOB_IMG_URL;
// 完整 API 地址
const fullApiUrl = apiUrl + apiPrefix; // 如 "/api" 或 "https://api.example.com/api"VITE_ 前缀
只有以 VITE_ 开头的环境变量才会暴露给客户端代码,其他变量(如 PORT)不会被访问到。
vite.config.ts import { defineConfig, loadEnv } from 'vite';
export default defineConfig(({ mode }) => {
// 加载环境变量
const env = loadEnv(mode, process.cwd());
return {
// 开发服务器
server: {
port: Number(env.VITE_PORT) || 8001,
proxy: {
'/api': {
target: 'http://admin.thinkphp6.elevue/api',
changeOrigin: true,
},
},
},
// 构建配置
build: {
// 生产环境删除 console
drop: env.VITE_DROP_CONSOLE === 'true' ? ['console', 'debugger'] : [],
// 启用 gzip 压缩
rollupOptions: {
output: {
manualChunks: {
vue: ['vue', 'vue-router', 'pinia'],
element: ['element-plus'],
},
},
},
},
};
});// 开发环境代理配置
server: {
proxy: {
'/api': {
target: 'http://admin.thinkphp6.elevue/api', // 目标地址
changeOrigin: true, // 修改请求头 Origin
rewrite: (path) => path.replace(/^\/api/, ''), // 路径重写(可选)
},
},
}代理效果:
前端请求: GET /api/user/page
│
▼ Vite proxy
│
▼ 转发到: http://admin.thinkphp6.elevue/api/user/page# 开发服务器(热更新)
pnpm dev
# 构建生产版本
pnpm build
# 预览构建结果(本地启动静态服务器)
pnpm preview
# ESLint 检查
pnpm lint:eslint
# ESLint 自动修复
pnpm lint:eslint --fix
# TypeScript 类型检查
pnpm type:checkui/dist/
├── index.html # 入口文件
├── assets/
│ ├── index-xxx.js # 主 JS(带 hash)
│ ├── index-xxx.css # 主 CSS(带 hash)
│ ├── vue-xxx.js # Vue 相关(分包)
│ └── element-xxx.js # Element Plus(分包)
├── favicon.ico
└── static/ # 静态资源server {
listen 80;
server_name admin.example.com;
# 前端静态文件
root /data/www/admin/dist;
index index.html;
# SPA 路由(所有非文件请求都返回 index.html)
location / {
try_files $uri $uri/ /index.html;
}
# API 代理到后端
location /api/ {
proxy_pass http://127.0.0.1:8080/api/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# 静态资源缓存
location /assets/ {
expires 30d;
add_header Cache-Control "public, immutable";
}
# Gzip 压缩
gzip on;
gzip_static on; # 优先使用 .gz 文件
gzip_types text/css application/javascript application/json;
}# .env.staging
VITE_GLOB_API_URL =
VITE_GLOB_API_URL_PREFIX = /api
VITE_GLOB_IMG_URL = https://test-cdn.example.com
VITE_DROP_CONSOLE = true构建命令:
pnpm build --mode staging| 变量 | 开发 | 测试 | 生产 |
|---|---|---|---|
VITE_PORT | 8001 | - | - |
VITE_GLOB_API_URL | 留空 | 留空 | 留空 |
VITE_GLOB_API_URL_PREFIX | /api | /api | /api |
VITE_GLOB_IMG_URL | http://file.xxx | https://test-cdn.xxx | https://cdn.xxx |
VITE_DROP_CONSOLE | false | true | true |
VITE_USE_MOCK | false | false | false |
原因: 代理配置错误或后端未启动。
解决: 检查 .env.development 中 VITE_PROXY 的目标地址是否正确。
原因: VITE_GLOB_API_URL 配置了跨域地址但后端未配置 CORS。
解决: 推荐留空,由 Nginx 代理处理(同域无跨域问题)。
原因: VITE_GLOB_IMG_URL 配置错误。
解决: 检查图片访问地址是否正确,确保图片 URL 可直接访问。
原因: 未启用 gzip 压缩或未分包。
解决: 启用 VITE_BUILD_COMPRESS = gzip,配置 manualChunks 分包。