11 KiB
9.3 环境与构建配置
:::tip 概述
本节说明前端项目的环境变量配置和 Vite 构建配置,包括开发环境和生产环境的差异配置。前端通过 .env 文件管理环境变量,Vite 自动根据模式加载对应的 .env 文件。
:::
环境变量文件
ui/
├── .env # 所有环境通用配置(端口、标题)
├── .env.development # 开发环境(pnpm dev,默认 mode)
├── .env.production # 生产构建(pnpm build / pnpm build:prod)
└── .env.test # 测试构建(pnpm build:test)
加载优先级: .env.{mode} > .env(Vite 标准加载规则,可用 .env.{mode}.local 做本地覆盖)
开发环境配置
.env.development
# 只在开发模式中被载入
VITE_PORT = 8001
# 网站根目录
VITE_PUBLIC_PATH = /
# 是否开启mock
VITE_USE_MOCK = false
# 网站前缀
VITE_BASE_URL = /
# 是否删除console
VITE_DROP_CONSOLE = true
# 跨域代理,可以配置多个,请注意不要换行
VITE_PROXY=[["/api","http://admin.laravel13.naivevue/api"]]
# API 接口地址
VITE_GLOB_API_URL =
# 图片上传地址
VITE_GLOB_UPLOAD_URL =
# 图片前缀地址
VITE_GLOB_IMG_URL =
# 接口前缀
VITE_GLOB_API_URL_PREFIX = /api
:::tip 代理目标地址
VITE_PROXY 是开发代理的唯一配置来源,当前值指向 Laragon 虚拟主机 http://admin.laravel13.naivevue/api(见 2.2 Laragon 环境搭建)。修改后需重启 pnpm dev 生效。
:::
生产环境配置
.env.production
# 是否开启mock
VITE_USE_MOCK = false
# 网站根目录
VITE_PUBLIC_PATH = /
# 网站前缀
VITE_BASE_URL = /
# 是否删除console
VITE_DROP_CONSOLE = true
# API
VITE_GLOB_API_URL =
# 图片上传地址
VITE_GLOB_UPLOAD_URL =
# 图片前缀地址
VITE_GLOB_IMG_URL =
# 接口前缀
VITE_GLOB_API_URL_PREFIX = /api
# 是否启用gzip压缩或brotli压缩
# 可选: gzip | brotli | none
# 如果你需要多种形式,你可以用','来分隔
VITE_BUILD_COMPRESS = 'none'
# 使用压缩时是否删除原始文件,默认为false
VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE = false
:::info 生产环境没有 VITE_PROXY
VITE_PROXY 仅在开发模式由 Vite dev server 使用;生产环境由 Nginx 反向代理 /api(见下方部署配置)。
:::
环境变量详解
VITE_PORT — 开发服务器端口
| 环境 | 值 | 说明 |
|---|---|---|
| 开发 | 8001 |
前端开发服务器端口 |
| 生产 | 不生效 | 生产环境由 Nginx 提供服务 |
VITE_PUBLIC_PATH — 公共基础路径
| 场景 | 值 | 说明 |
|---|---|---|
| 根目录部署 | / |
默认值 |
| 子目录部署 | /admin/ |
如 https://example.com/admin/ |
VITE_GLOB_API_URL — API 基础路径
| 场景 | 值 | 说明 |
|---|---|---|
| 开发(代理) | 留空 | 由 Vite proxy 转发 |
| 生产(同域) | 留空 | 由 Nginx 代理 |
| 生产(跨域) | https://api.example.com |
直接请求后端域名(需后端 CORS 放行) |
VITE_PROXY — 开发代理配置
# .env.development 中的值(指向 Laragon 虚拟主机)
VITE_PROXY=[["/api","http://admin.laravel13.naivevue/api"]]
格式: JSON 数组,每项为 [前缀, 目标地址]
作用: 将前端 /api/* 请求代理到后端地址,解决开发环境跨域问题(代理方式下不依赖后端 CORS 配置)。
多代理示例:
VITE_PROXY = [["/api","http://admin.laravel13.naivevue/api"],["/uploads","http://admin.laravel13.naivevue/uploads"]]
VITE_GLOB_API_URL_PREFIX — API 前缀
VITE_GLOB_API_URL_PREFIX = /api
所有 API 请求路径的前缀,与后端路由前缀一致(bootstrap/app.php 统一添加 /api)。
VITE_GLOB_UPLOAD_URL — 上传接口地址
VITE_GLOB_UPLOAD_URL=
文件上传组件使用的接口地址(实际调用 /api/upload/uploadFile)。当前项目留空——上传走同域/开发代理,跨域部署时再配置为后端完整地址。
VITE_GLOB_IMG_URL — 图片访问地址
VITE_GLOB_IMG_URL=
用于预览上传的图片,拼接图片的完整 URL。当前项目留空(后端 get_file_url() 已按 FILE_DOMAIN_URL 补全域名);如配置,必须与后端 FILE_DOMAIN_URL 保持一致,否则同一张图片前后端解析出不同地址。
VITE_DROP_CONSOLE — 删除 console
# 当前项目开发与生产构建均为 true(删除 console)
VITE_DROP_CONSOLE = true
# 需要调试时可在本地改为 false
VITE_BUILD_COMPRESS — Gzip 压缩
# 当前默认关闭
VITE_BUILD_COMPRESS = 'none'
# 可选:gzip / brotli(多个用逗号分隔),启用后构建产物生成 .gz 文件,
# Nginx 配置 gzip_static on 可直接使用
VITE_BUILD_COMPRESS = 'gzip'
在代码中访问环境变量
// 读取环境变量(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"
:::warning VITE_ 前缀
只有以 VITE_ 开头的环境变量才会暴露给客户端代码,其他变量(如 PORT)不会被访问到。
:::
Vite 配置
vite.config.ts
// ui/vite.config.ts(摘自实际代码,节选)
export default ({ command, mode }: ConfigEnv): UserConfig => {
const root = process.cwd();
const env = loadEnv(mode, root);
const viteEnv = wrapperEnv(env); // VITE_PROXY 在此由字符串 JSON.parse 为数组(见 build/utils.ts)
const { VITE_PUBLIC_PATH, VITE_PORT, VITE_GLOB_PROD_MOCK, VITE_PROXY } = viteEnv;
return {
base: VITE_PUBLIC_PATH,
server: {
host: true,
port: VITE_PORT, // 端口来自 .env.development 的 VITE_PORT
proxy: createProxy(VITE_PROXY), // 见 build/vite/proxy.ts
},
// ... 插件、路径别名等见 ui/vite.config.ts 全文
};
};
// ui/build/utils.ts —— wrapperEnv 中对 VITE_PROXY 做 JSON 解析
if (envName === 'VITE_PROXY') {
try {
realName = JSON.parse(realName);
} catch (error) {}
}
// ui/build/vite/proxy.ts —— 由 [前缀, 目标] 数组生成代理规则
export function createProxy(list: ProxyList = []) {
const ret: ProxyTargetList = {};
for (const [prefix, target] of list) {
ret[prefix] = {
target,
changeOrigin: true,
ws: true,
rewrite: (path) => path.replace(new RegExp(`^${prefix}`), ''), // 去掉前缀再转发
};
}
return ret;
}
代理配置详解
// createProxy 为每个 [前缀, 目标] 生成的规则(ui/build/vite/proxy.ts 实际逻辑)
server: {
proxy: {
'/api': {
target: 'http://admin.laravel13.naivevue/api', // 目标地址(VITE_PROXY 驱动,含 /api 前缀)
changeOrigin: true, // 修改请求头 Origin
ws: true, // 支持 WebSocket
rewrite: (path) => path.replace(new RegExp('^/api'), ''), // 去掉前缀,由目标地址补回
},
},
}
代理效果:
前端请求: GET /api/user/page
│
▼ Vite proxy
│
▼ 转发到: http://admin.laravel13.naivevue/api/user/page
构建命令
# 开发服务器(热更新)
pnpm dev
# 构建生产版本
pnpm build
# 预览构建结果(本地启动静态服务器)
pnpm preview
# ESLint 检查 / 自动修复
pnpm lint:eslint
pnpm lint:eslint --fix
# TypeScript 类型检查
pnpm type:check
构建产物
ui/dist/
├── index.html # 入口文件
├── assets/
│ ├── index-xxx.js # 主 JS(带 hash)
│ ├── index-xxx.css # 主 CSS(带 hash)
│ └── vue-xxx.js # Vue 相关(分包)
├── favicon.ico
└── static/ # 静态资源
部署配置
Nginx 配置
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:8000/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.test(pnpm build:test)
VITE_USE_MOCK = true
VITE_PUBLIC_PATH = /
VITE_BASE_URL = /
VITE_DROP_CONSOLE = true
VITE_GLOB_API_URL =
VITE_GLOB_UPLOAD_URL =
VITE_GLOB_IMG_URL =
VITE_GLOB_API_URL_PREFIX = /api
VITE_BUILD_COMPRESS = 'none'
VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE = false
构建命令(见 ui/package.json scripts):
pnpm build:test # 测试环境构建
pnpm build:prod # 生产环境构建(与 pnpm build 等价)
环境变量对照表
| 变量 | 开发 | 测试 | 生产 |
|---|---|---|---|
VITE_PORT |
8001 | - | - |
VITE_BASE_URL |
/ | / | / |
VITE_GLOB_API_URL |
留空 | 留空 | 留空 |
VITE_GLOB_API_URL_PREFIX |
/api | /api | /api |
VITE_PROXY |
[["/api","http://admin.laravel13.naivevue/api"]] |
- | - |
VITE_GLOB_IMG_URL |
留空 | 留空 | 留空(按需配置 CDN) |
VITE_DROP_CONSOLE |
true | true | true |
VITE_USE_MOCK |
false | true | false |
常见问题
问题 1:开发环境 API 请求 404
原因: 代理配置错误或后端未启动。
解决: 检查 .env.development 中 VITE_PROXY 的目标地址是否正确,curl http://admin.laravel13.naivevue/api/captcha 验证后端;改完配置重启 pnpm dev。
问题 2:生产环境 API 请求跨域
原因: VITE_GLOB_API_URL 配置了跨域地址但后端未配置 CORS。
解决: 推荐留空,由 Nginx 代理处理(同域无跨域问题);确需跨域时在后端 .env 配置 CORS_ALLOW_ORIGIN(见 5.5 跨域资源共享)。
问题 3:图片不显示
原因: VITE_GLOB_IMG_URL 与后端 FILE_DOMAIN_URL 不一致。
解决: 两者保持一致;改后端配置需 php artisan config:clear。
问题 4:构建后体积过大
原因: 未启用 gzip 压缩或未分包。
解决: 启用 VITE_BUILD_COMPRESS = gzip,配置 manualChunks 分包。