签入版本

This commit is contained in:
2026-10-08 17:50:29 +08:00
parent 809750b47e
commit e213a9b31d
444 changed files with 39366 additions and 37533 deletions
@@ -8,13 +8,15 @@
```text
ui/
├── .env # 所有环境通用配置
├── .env.development # 开发环境配置
├── .env.production # 生产环境配置
└── .env.local # 本地覆盖(不提交 git)
├── .env # 所有环境通用配置(端口、标题)
├── .env.development # 开发环境(pnpm dev,默认 mode)
├── .env.production # 生产构建(pnpm build)
├── .env.test # 测试构建(pnpm build:test)
├── .env.uat # UAT 构建(pnpm build:uat)
└── .env.dev # dev 模式构建(pnpm build:dev)
```
**加载优先级:** `.env.local` > `.env.{mode}` > `.env`
**加载优先级:** `.env.{mode}` > `.env`(Vite 标准加载规则,可用 `.env.{mode}.local` 做本地覆盖)
## 开发环境配置
@@ -27,53 +29,65 @@ VITE_PORT = 8001
# 公共基础路径(通常为 /)
VITE_PUBLIC_PATH = /
# 是否启用 Mock 数据(false = 使用真实后端 API)
VITE_USE_MOCK = false
# 是否删除 console(当前项目开发构建同样删除)
VITE_DROP_CONSOLE = true
# 开发代理(JSON 数组格式:[["前缀","目标地址"]])
VITE_PROXY=[["/api","http://admin.laravel13.elevue/api"]]
# API 接口基础路径(留空,由代理处理)
VITE_GLOB_API_URL =
# 上传接口地址(留空,走同域/代理)
VITE_GLOB_UPLOAD_URL=
# 图片前缀地址(留空,按后端返回的地址解析)
VITE_GLOB_IMG_URL=
# 构建压缩方式:none / gzip / brotli
VITE_BUILD_COMPRESS = 'none'
VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE = false
# 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
```
:::tip 代理目标地址
`VITE_PROXY` 当前默认指向 Laragon 虚拟主机 `http://admin.laravel13.elevue/api`;使用 `php artisan serve` 时改为直连 `http://localhost:8000/api`(见 [2.2 Laragon 环境搭建](/zh/quickstart/laragon.html))。修改后需重启 `pnpm dev`。
:::
## 生产环境配置
### `.env.production`
```bash
# 是否启用 Mock 数据
VITE_USE_MOCK = false
# 公共基础路径(通常为 /,如部署到子目录则设为 /subdir/)
VITE_PUBLIC_PATH = /
# 是否删除 console
VITE_DROP_CONSOLE = true
# API 接口基础路径(留空,由 Nginx 代理处理)
VITE_GLOB_API_URL =
# 上传接口地址(留空,走同域)
VITE_GLOB_UPLOAD_URL=
# 图片前缀地址(留空;跨域部署时配置 CDN/后端域名,与 FILE_DOMAIN_URL 一致)
VITE_GLOB_IMG_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
# 构建压缩方式(当前默认 none;可选 gzip / brotli)
VITE_BUILD_COMPRESS = 'none'
# 压缩后是否删除原文件
VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE = false
@@ -83,10 +97,6 @@ VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE = false
### VITE_PORT — 开发服务器端口
```bash
VITE_PORT = 8001
```
| 环境 | 值 | 说明 |
|------|-----|------|
| 开发 | `8001` | 前端开发服务器端口 |
@@ -94,10 +104,6 @@ VITE_PORT = 8001
### VITE_PUBLIC_PATH — 公共基础路径
```bash
VITE_PUBLIC_PATH = /
```
| 场景 | 值 | 说明 |
|------|-----|------|
| 根目录部署 | `/` | 默认值 |
@@ -105,30 +111,30 @@ VITE_PUBLIC_PATH = /
### VITE_GLOB_API_URL — API 基础路径
```bash
VITE_GLOB_API_URL =
```
| 场景 | 值 | 说明 |
|------|-----|------|
| 开发(代理) | 留空 | 由 Vite proxy 转发 |
| 生产(同域) | 留空 | 由 Nginx 代理 |
| 生产(跨域) | `https://api.example.com` | 直接请求后端域名 |
| 生产(跨域) | `https://api.example.com` | 直接请求后端域名(需后端 CORS 放行) |
### VITE_PROXY — 开发代理配置
```bash
VITE_PROXY = [["/api","http://admin.thinkphp6.elevue/api"]]
# 当前 .env.development 中的值(Laragon 虚拟主机)
VITE_PROXY=[["/api","http://admin.laravel13.elevue/api"]]
# 直连 artisan serve 时的写法
VITE_PROXY=[["/api","http://localhost:8000/api"]]
```
**格式:** JSON 数组,每项为 `[前缀, 目标地址]`
**作用:** 将前端 `/api/*` 请求代理到后端地址,解决开发环境跨域问题。
**作用:** 将前端 `/api/*` 请求代理到后端地址,解决开发环境跨域问题(代理方式下不依赖后端 CORS 配置)。
**多代理示例:**
```bash
VITE_PROXY = [["/api","http://localhost:8080/api"],["/upload","http://localhost:8080/upload"]]
VITE_PROXY = [["/api","http://localhost:8000/api"],["/uploads","http://localhost:8000/uploads"]]
```
### VITE_GLOB_API_URL_PREFIX — API 前缀
@@ -137,45 +143,43 @@ VITE_PROXY = [["/api","http://localhost:8080/api"],["/upload","http://localhost:
VITE_GLOB_API_URL_PREFIX = /api
```
所有 API 请求路径的前缀,与后端路由前缀一致。
所有 API 请求路径的前缀,与后端路由前缀一致(`bootstrap/app.php` 统一添加 `/api`)。
### VITE_GLOB_UPLOAD_URL — 上传接口地址
```bash
VITE_GLOB_UPLOAD_URL = /api/upload
VITE_GLOB_UPLOAD_URL=
```
文件上传组件使用的接口地址。
文件上传组件使用的接口地址(实际调用 `/api/upload/uploadFile`)。**当前项目留空**——上传走同域/开发代理,跨域部署时再配置为后端完整地址。
### VITE_GLOB_IMG_URL — 图片访问地址
```bash
# 开发环境
VITE_GLOB_IMG_URL = http://file.thinkphp6.elevue
# 生产环境
VITE_GLOB_IMG_URL = https://cdn.example.com
VITE_GLOB_IMG_URL=
```
用于预览上传的图片,拼接图片的完整 URL。
用于预览上传的图片,拼接图片的完整 URL。**当前项目留空**(后端 `get_file_url()` 已按 `FILE_DOMAIN_URL` 补全域名);如配置,**必须与后端 `FILE_DOMAIN_URL` 保持一致**,否则同一张图片前后端解析出不同地址。
### VITE_DROP_CONSOLE — 删除 console
```bash
# 开发环境:保留 console(方便调试)
VITE_DROP_CONSOLE = false
# 生产环境:删除 console(安全+减小体积)
# 当前项目开发与生产构建均为 true(删除 console)
VITE_DROP_CONSOLE = true
# 需要调试时可在本地改为 false
```
### VITE_BUILD_COMPRESS — Gzip 压缩
```bash
VITE_BUILD_COMPRESS = gzip
```
# 当前默认关闭
VITE_BUILD_COMPRESS = 'none'
启用 gzip 压缩后,构建产物会生成 `.gz` 文件,Nginx 配置 `gzip_static on` 可直接使用。
# 可选:gzip / brotli(多个用逗号分隔),启用后构建产物生成 .gz 文件,
# Nginx 配置 gzip_static on 可直接使用
VITE_BUILD_COMPRESS = 'gzip'
```
## 在代码中访问环境变量
@@ -199,52 +203,53 @@ const fullApiUrl = apiUrl + apiPrefix; // 如 "/api" 或 "https://api.example.c
### `vite.config.ts`
```typescript
import { defineConfig, loadEnv } from 'vite';
// ui/vite.config.ts(摘自实际代码,节选)
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,
},
},
},
// VITE_PROXY 容错处理:未配置时使用空代理
let VITE_PROXY: any = viteEnv.VITE_PROXY;
if (!VITE_PROXY) {
VITE_PROXY = '[[]]'; // 默认空代理
}
if (typeof VITE_PROXY === 'string') {
VITE_PROXY = JSON.parse(VITE_PROXY);
}
// 构建配置
build: {
// 生产环境删除 console
drop: env.VITE_DROP_CONSOLE === 'true' ? ['console', 'debugger'] : [],
// 启用 gzip 压缩
rollupOptions: {
output: {
manualChunks: {
vue: ['vue', 'vue-router', 'pinia'],
element: ['element-plus'],
},
},
},
return {
server: {
proxy: createProxy(VITE_PROXY), // 见 build/vite/proxy.ts
},
// ... 插件、路径别名等见 ui/vite.config.ts 全文
};
});
// 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;
}
```
### 代理配置详解
```typescript
// 开发环境代理配置
// createProxy 为每个 [前缀, 目标] 生成的规则(ui/build/vite/proxy.ts 实际逻辑)
server: {
proxy: {
'/api': {
target: 'http://admin.thinkphp6.elevue/api', // 目标地址
changeOrigin: true, // 修改请求头 Origin
rewrite: (path) => path.replace(/^\/api/, ''), // 路径重写(可选)
target: 'http://localhost:8000/api', // 目标地址(VITE_PROXY 驱动,含 /api 前缀)
changeOrigin: true, // 修改请求头 Origin
ws: true, // 支持 WebSocket
rewrite: (path) => path.replace(new RegExp('^/api'), ''), // 去掉前缀,由目标地址补回
},
},
}
@@ -257,7 +262,7 @@ server: {
│
▼ Vite proxy
│
▼ 转发到: http://admin.thinkphp6.elevue/api/user/page
▼ 转发到: http://localhost:8000/api/user/page
```
## 构建命令
@@ -272,10 +277,8 @@ pnpm build
# 预览构建结果(本地启动静态服务器)
pnpm preview
# ESLint 检查
# ESLint 检查 / 自动修复
pnpm lint:eslint
# ESLint 自动修复
pnpm lint:eslint --fix
# TypeScript 类型检查
@@ -316,7 +319,7 @@ server {
# API 代理到后端
location /api/ {
proxy_pass http://127.0.0.1:8080/api/;
proxy_pass http://127.0.0.1:8000/api/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
@@ -336,20 +339,23 @@ server {
## 多环境配置
### 测试环境
### 测试 / UAT 环境(项目实际提供)
```bash
# .env.staging
# .env.test(pnpm build:test)
VITE_GLOB_API_URL =
VITE_GLOB_API_URL_PREFIX = /api
VITE_GLOB_IMG_URL = https://test-cdn.example.com
VITE_DROP_CONSOLE = true
# .env.uat(pnpm build:uat)同结构,按需调整
```
构建命令:
构建命令(见 `ui/package.json` scripts):
```bash
pnpm build --mode staging
pnpm build:test # 测试环境构建
pnpm build:uat # UAT 环境构建
pnpm build:prod # 生产环境构建
```
### 环境变量对照表
@@ -359,8 +365,9 @@ 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_PROXY` | `[["/api","http://admin.laravel13.elevue/api"]]` | - | - |
| `VITE_GLOB_IMG_URL` | 留空 | 留空 | 留空(按需配置 CDN) |
| `VITE_DROP_CONSOLE` | true | true | true |
| `VITE_USE_MOCK` | false | false | false |
## 常见问题
@@ -369,19 +376,19 @@ pnpm build --mode staging
**原因:** 代理配置错误或后端未启动。
**解决:** 检查 `.env.development` 中 `VITE_PROXY` 的目标地址是否正确。
**解决:** 检查 `.env.development` 中 `VITE_PROXY` 的目标地址是否正确,`curl http://localhost:8000/api/captcha` 验证后端;改完配置重启 `pnpm dev`。
### 问题 2:生产环境 API 请求跨域
**原因:** `VITE_GLOB_API_URL` 配置了跨域地址但后端未配置 CORS。
**解决:** 推荐留空,由 Nginx 代理处理(同域无跨域问题)。
**解决:** 推荐留空,由 Nginx 代理处理(同域无跨域问题);确需跨域时在后端 `.env` 配置 `CORS_ALLOW_ORIGIN`(见 [5.5 跨域资源共享](/zh/core/cors.html))。
### 问题 3:图片不显示
**原因:** `VITE_GLOB_IMG_URL` 配置错误。
**原因:** `VITE_GLOB_IMG_URL` 与后端 `FILE_DOMAIN_URL` 不一致。
**解决:** 检查图片访问地址是否正确,确保图片 URL 可直接访问。
**解决:** 两者保持一致;改后端配置需 `php artisan config:clear`。
### 问题 4:构建后体积过大