Files
rxthinkcmf-wiki/RXThinkCMF_Laravel13_AntdVue/zh/frontend/env-config.md
T
2026-10-08 17:50:29 +08:00

11 KiB
Raw Blame History

9.3 环境与构建配置

:::tip 概述 本节说明前端项目的环境变量配置和 Vite 构建配置,包括开发环境和生产环境的差异配置。前端通过 .env 文件管理环境变量,Vite 自动根据模式加载对应的 .env 文件。 :::

环境变量文件

ui/
├── .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.{mode} > .env(Vite 标准加载规则,可用 .env.{mode}.local 做本地覆盖)

开发环境配置

.env.development

# 开发服务器端口
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

:::tip 代理目标地址 VITE_PROXY 当前默认指向 Laragon 虚拟主机 http://admin.laravel13.elevue/api;使用 php artisan serve 时改为直连 http://localhost:8000/api(见 2.2 Laragon 环境搭建)。修改后需重启 pnpm dev。 :::

生产环境配置

.env.production

# 是否启用 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

# 构建压缩方式(当前默认 none;可选 gzip / brotli)
VITE_BUILD_COMPRESS = 'none'

# 压缩后是否删除原文件
VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE = false

环境变量详解

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.elevue/api"]]

# 直连 artisan serve 时的写法
VITE_PROXY=[["/api","http://localhost:8000/api"]]

格式: JSON 数组,每项为 [前缀, 目标地址]

作用: 将前端 /api/* 请求代理到后端地址,解决开发环境跨域问题(代理方式下不依赖后端 CORS 配置)。

多代理示例:

VITE_PROXY = [["/api","http://localhost:8000/api"],["/uploads","http://localhost:8000/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 defineConfig(({ mode }) => {
  const env = loadEnv(mode, process.cwd());

  // 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);
  }

  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;
}

代理配置详解

// createProxy 为每个 [前缀, 目标] 生成的规则(ui/build/vite/proxy.ts 实际逻辑)
server: {
  proxy: {
    '/api': {
      target: 'http://localhost:8000/api',  // 目标地址(VITE_PROXY 驱动,含 /api 前缀)
      changeOrigin: true,                    // 修改请求头 Origin
      ws: true,                               // 支持 WebSocket
      rewrite: (path) => path.replace(new RegExp('^/api'), ''), // 去掉前缀,由目标地址补回
    },
  },
}

代理效果:

前端请求: GET /api/user/page
    │
    ▼ Vite proxy
    │
    ▼ 转发到: http://localhost:8000/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 相关(分包)
│   └── element-xxx.js      # Element Plus(分包)
├── 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;
}

多环境配置

测试 / UAT 环境(项目实际提供)

# .env.test(pnpm build:test)
VITE_GLOB_API_URL =
VITE_GLOB_API_URL_PREFIX = /api
VITE_DROP_CONSOLE = true

# .env.uat(pnpm build:uat)同结构,按需调整

构建命令(见 ui/package.json scripts):

pnpm build:test    # 测试环境构建
pnpm build:uat     # UAT 环境构建
pnpm build:prod    # 生产环境构建

环境变量对照表

变量 开发 测试 生产
VITE_PORT 8001 - -
VITE_GLOB_API_URL 留空 留空 留空
VITE_GLOB_API_URL_PREFIX /api /api /api
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

常见问题

问题 1:开发环境 API 请求 404

原因: 代理配置错误或后端未启动。

解决: 检查 .env.development 中 VITE_PROXY 的目标地址是否正确,curl http://localhost:8000/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 分包。