Skip to content

第 4 步:构建、部署与验收 ​

前提:前三章已经跑通真实请求、独立登录和订单保存返回。下面将基座和子应用部署到同一个 HTTPS 域名,统一 /api 网关,避免第一次上线同时引入跨源 Cookie 和跨源资源配置。

教学 API 只能用于本机验证。上线时由后端实现同样的协议或修改项目适配器,补齐真实用户、权限、订单资源归属、持久化、Secure Cookie 和 CSRF 校验。

1. 确定最终地址 ​

用途本章示例
基座https://portal.example.com/
子应用 HTML 入口https://portal.example.com/apps/order/
子应用独立入口https://portal.example.com/apps/order/#/home
API 网关https://portal.example.com/api/

example.com 地址需要替换为自己已配置 DNS 与证书的域名。entry 配置到子应用 HTML 所在目录,不带 #/list 或 /detail。

2. 配置生产变量 ​

my-host/.env.production:

dotenv
VITE_AUTH_DEMO=false
VITE_MICRO_APP_ID=order
VITE_MICRO_APP_ENTRY=https://portal.example.com/apps/order/
VITE_API_BASE=/api/
VITE_TRUSTED_API_BASE=/api/
VITE_API_CREDENTIALS=true

order-app/.env.production:

dotenv
VITE_MICRO_AUTH_MODE=auto
VITE_API_BASE=/api/
VITE_TRUSTED_API_BASE=/api/
VITE_API_CREDENTIALS=true

Vite 的生产模式会使用这些配置;显式导出的进程环境变量优先级更高,CI 中也要检查。VITE_* 在构建时写入浏览器产物,改配置后必须重新构建,不能把 Token、密码或固定 CSRF 值放进去。

基座仍使用第二章的 platformSecurity.ts,从服务端读取 CSRF;生产缺值拒绝发送登录/注销请求。子应用独立认证和订单写接口也必须保留其 CSRF 接线。

3. 配置子应用静态资源 base ​

将 order-app/vite.config.ts 改为以下结构,开发仍使用根目录,构建时使用部署子目录:

ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

export default defineConfig(({ command }) => ({
  base: command === 'build' ? '/apps/order/' : '/',
  plugins: [vue()],
  server: {
    port: 7101,
    strictPort: true,
    cors: { origin: ['http://localhost:7100', 'http://localhost:7101'], credentials: true },
    proxy: { '/api': { target: 'http://127.0.0.1:7200', changeOrigin: true } },
  },
}))

基座部署在根目录,base 保持默认。子应用使用 hash 路由,嵌入时使用 memory history;不要为修复静态资源路径而改掉这些路由模式。

4. 分别检查和构建 ​

在两个项目目录各执行:

sh
npm run check:runtime
npm run typecheck
npm run build

每个项目都会生成自己的 dist。构建失败时先处理版本、类型和资源问题;vite preview 仅用于本地预览,不能替代生产服务器与 API 网关。

5. 部署目录与服务器示例 ​

将两个 dist 的内容分别部署为:

text
/srv/fin/
├─ host/
│  ├─ index.html
│  └─ assets/
└─ apps/order/
   ├─ index.html
   └─ assets/

下面是 Nginx server 内的 location 示例;外层 HTTPS、证书、server_name 由实际部署配置提供,backend-service:8080 替换为真实后端。

nginx
root /srv/fin;

# /api 不得落入 SPA 的 index.html;后端收到原始 /api/... 路径。
location /api/ {
    proxy_pass http://backend-service:8080;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

# 子应用目录使用与 Vite base 一致的资源路径。
location ^~ /apps/order/ {
    try_files $uri $uri/ /apps/order/index.html;
}

# 基座使用 history 路由,刷新 /home、/micro/order/detail 等地址须回到基座入口。
location / {
    root /srv/fin/host;
    try_files $uri $uri/ /index.html;
}

这里两个前端同源,Wujie 资源无需额外跨源 CORS。未来拆成不同域名时,须分别配置子应用静态资源 CORS、API CORS、Cookie 策略和 CSP;开发服务器 cors/proxy 不会进入生产服务器。具体边界见平台适配与生产配置。

/micro/ 是基座的业务导航前缀,不能作为子应用静态资源部署目录;上述子应用资源使用 /apps/order/。宿主不再解析 /workspace?tab=...,旧书签需要改为 /micro/{appId}/{原业务路径}?query。

6. 上线前逐项验收 ​

操作应看到的结果
无痕打开基座未登录先显示登录页,无工作区数据
真实账号登录认证、menus、工作区按顺序就绪,无演示身份降级
从菜单打开订单列表子应用 HTML、JS、CSS 200,业务接口获得合法身份
打开两个不同订单独立页签、独立参数和草稿,同一订单不重复创建
保存备注后端成功后才关闭详情,列表更新
刷新 /micro/order/detail?id=1001Nginx 返回基座 HTML,先恢复身份再恢复授权页签
独立打开子应用无会话时登录,有会话时恢复;本地菜单可用
移除读取权限后重新登录菜单/页面准入按新权限检查,后端也拒绝越权资源
移除写权限保存按钮不可用,直接请求写 API 也被后端拒绝
注销或会话过期撤销身份和业务内容,旧请求不能恢复旧用户
CSRF 缺失或错误服务端拒绝写请求,不通过关闭保护来解决

浏览器检查 Console 和 Network,不能仅凭构建成功判断生产接入完成。教学服务固定权限,不用于验证真实的多租户、角色管理和数据库事务;这些由实际后端验收。

仓库维护者:生产构建检查 ​

在仓库根执行:

sh
pnpm check:production
pnpm --filter @axewo/fin-ui lint:check

该流程验证当前生产范围内五个包的类型、构建、ESM/CJS 入口、声明引用和微前端发布清单,同时构建文档站及 playground,不发布 npm。测试用例与历史临时消费者工程已清理,fin-dashboard 与 fin-editor 暂不纳入生产范围。

生成或迁移项目后,仍须执行项目内的 check:runtime、typecheck 和 build,并按本章完成真实后台及部署验收。