# 需求:admin-cli-生成的-Vben-后台生产构建整页白屏-产物缺-_app.config.js(window._VBEN_ADMIN_PRO_APP_CONF_-没注入)

状态: done(2026-10-20 已上线:模板 7da654a 自建 _app.config.js 注入插件 + 产物自检 5 条 + 真 Edge 渲染校验 PASS（#app 900px、未捕获异常 0）；admin-core 0.1.8 已发 Verdaccio（tarball 内 CSS 136B 实测）；远端 -v main 端到端复验 PASS)
归属: 主会话(Admin_Template 主)
来源: 登记缺口(ops/products/#onboard-hub)
日期: 2026-10-16
建议: 做,2026-10-16 入职中间件部署到 NAS 后实测:首页 HTTP 200、index.html/CSS/入口 JS 全 200,浏览器整页白屏。headless Edge 抓原始报错:Cannot destructure property 'VITE_GLOB_API_URL' of 'n' as it is undefined —— admin-core 的 API 地址取自运行期全局 window._VBEN_ADMIN_PRO_APP_CONF_(见 @admin-template/admin-core dist:const { VITE_GLOB_API_URL } = window._VBEN_ADMIN_PRO_APP_CONF_),而生成器产物既没产出 _app.config.js、index.html 也没引用它。模板仓自己的参照工程 examples/external-admin-web/dist/ 同样缺(App 的 HTML 也不做 EJS 处理,<title><%= VITE_APP_TITLE %> 原样输出),说明这条链从未在生产构建下验收过。凡 admin-cli create 出的后台都会白屏,不止本产品。

## 现状

- 盘点缺口来源产品:onboard-hub
- **症状**:`admin-cli create`(及模板仓参照工程 `examples/external-admin-web`)产出的后台,`pnpm build` 后由静态服务器托管,**首页 HTTP 200、index.html 200、CSS 200、入口 JS 200,浏览器却整页白屏**,`<div id="app">` 子节点数 0。
- **原始报错**(2026-10-16 NAS 部署后 headless Edge 抓到,非推测):
  `[pageerror] Cannot destructure property 'VITE_GLOB_API_URL' of 'n' as it is undefined. at index-*.js:186`
- **根因**:admin-core 的 API 地址不是构建期内联值,而是**运行期读全局** `window._VBEN_ADMIN_PRO_APP_CONF_`。admin-core 产物原文:
  `function Bye(e,t){const n=window._VBEN_ADMIN_PRO_APP_CONF_,{VITE_GLOB_API_URL:o}=n;return{apiURL:o}}`
  该全局本应由构建产物根部的 `_app.config.js` 注入并被 `index.html` 在入口之前引用;生成器**两件都没做**:产物里没有 `_app.config.js`,`index.html` 里也没有 `<script src="/_app.config.js">`。于是全局 undefined → 入口函数解构即抛 → Vue 从未挂载 → 白屏。
- **旁证 1**:模板仓自己的 `examples/external-admin-web/dist/`(参照工程的构建产物)同样无 `_app.config.js`,其 bundle 里同样残留 `VITE_GLOB_API_URL` 字面量 → **这条链从未在生产构建下验收过**(开发态 `vite dev` 不暴露此缺陷)。
- **旁证 2**:同一产物的 `<title><%= VITE_APP_TITLE %></title>` 原样输出(该模板的 HTML 不做 EJS 处理),浏览器标签页显示的是占位符文本 —— 同一族"构建期该做的注入没人做"。
- **影响面**:凡 `admin-cli create` 生成的后台项目,部署到静态托管即白屏;onboard-hub 是第一个踩到的(2026-10-16 骨架部署),不修则每个外部项目都要再踩一次。
- **为什么冒烟没抓到**:部署冒烟当时只断言 HTTP 状态码(全 200),而白屏是"资源都在、JS 跑挂",状态码层面完全正常。
- **同族缺陷(2026-10-16 同轮排查,一并记录,同一批产物)**:
  - **b. admin-cli 生成的 `tailwind.config.mjs` 漏扫 pnpm 虚拟 store,布局包的工具类整批不生成**(2026-10-16 第二轮定位到真因,此前只看到"`.min-h-full` 查无"的现象):admin-core 的认证布局来自 **`@vben/layouts`**,而它是 admin-core 的**传递依赖** —— pnpm 把它放在 `node_modules/.pnpm/**` 下,不在顶层 `node_modules/@vben/*`;而生成器给的 `content` 只写了顶层 glob(src/dist 各三条)。后果:该包里的工具类一个都不生成(实测缺 `w-[34%]`、`w-2/5`、`min-h-full`),登录页从官方的「左侧 66% 品牌面板(渐变+插画+标语)+ 右侧 34% 表单」**塌成「白底 + 居中表单」**,而 HTTP 全 200、接口全绿,只有真渲染/人眼看得出(老板原话「这个排版不对,我记得 vben 官方是没有这问题的」)。另:该配置还缺 Vben 自定义动画工具类 `animate-float` 的 keyframes 定义(官方 monorepo 放在 `internal/tailwind-config`,业务仓拿不到)→ 官方插画不浮动。**修法**:`content` 补 `.pnpm` globs(`./node_modules/.pnpm/**/node_modules/@vben/*/dist/**` 等三条);**根治应在生成器**:生成的 tailwind 配置必须覆盖 pnpm 虚拟 store(npm/yarn 扁平布局另论),或改用 Vben 官方 tailwind 预设包。
  - **c. admin-core 的 `dist/styles/index.css` 是 0 字节**(基线样式全空,`html/body/#app` 没人给高度)。叠加 b 之后:登录页容器在 1440×900 下只有 332px 高,底部「版权+设置」浮层直接压在「登录」按钮上 —— 视觉重叠 + **吞掉鼠标点击**(Playwright 普通 click 超时,只有回车或点按钮边缘能提交)。
  - **c. 后端菜单 `component` 字段与视图清单错位**:种子给的 dashboard 菜单是 `dashboard/analytics/index`,而生成器产出的视图文件是 `views/dashboard/index.vue` → 动态路由解析不到组件(正是 `router/pages.ts` 注释警告的"下拉里选得到、构建产物里解析不到,点进去就是白屏")。业务仓当时的绕法是补一条**同路径静态路由**兜住,后果是**该页游离在后台布局之外**(登录后首屏没有侧栏菜单,看着"不像后台"),并且**未登录也能直接打开**(实测 `GET /` 落到裸 dashboard)。已改为:视图按菜单口径就位到 `views/dashboard/analytics/index.vue`、删掉静态业务路由、全部走菜单驱动。
  - **d. 登录页 logo 与后台默认头像走公网 CDN**:`https://unpkg.com/@vbenjs/static-source@0.1.7/source/logo-v1.webp` 与 `.../avatar-v1.webp` —— 内网系统不该依赖公网可取性。**2026-10-16 21:0x 老板实测**:他的机器上 CDN 不通,登录页左上角品牌区变成碎图 + 文字挤成多行重叠(本地按「断掉 unpkg」复现完全一致:`<img>` `naturalWidth=0`、碎图占位被撑成 42×71,品牌行随之变形;对照组 CDN 通时 `naturalWidth=1104×944`、行高 36)。业务仓处置=资产随产物自托管 + 偏好覆盖;模板侧应改为**默认自托管**(不要求用模板的人自己发现)。另:偏好里 `logo` 是**顶层节**、不在 `app` 下,写错层级会**静默**用回 CDN 默认值(业务仓本轮踩过)。
  - **f. 登录页页脚挂着模板方品牌**:`Copyright © 2024 Vben` + `vben.pro` 外链(admin-core 默认 `copyright.companyName`),生成器未按项目口径覆盖 → 交付给客户的系统页脚写着别人的品牌。
  - **e. 登录守卫的 redirect 参数被双重编码**:未登录访问 `/` 得到 `#/auth/login?redirect=%252Fdashboard%252Fanalytics`(`%252F` = `%2F` 再编码一次),登录后回跳目标可能解析失败。

## 方案

1. **admin-core 侧(根治,模板主会话代改)**:把运行期配置做成包内一等公民 —— 由 admin-core 提供 `adminRuntimeConfig()` Vite 插件(或明确的构建约定文档):构建时按 `.env.<mode>` 产出 `_app.config.js` 并在 `index.html` 头部首位注入;顺带处理 `<%= ... %>` 占位(改为标准 `%VITE_APP_TITLE%` 或由同一插件替换)。
2. **生成器侧(`admin-cli create`)**:模板里带上该插件与产物自检,使新项目出生即带 `_app.config.js`。
3. **参照工程 `examples/external-admin-web`**:同步修好并**在仓内留下生产构建产物自检**(至少断言 `dist/_app.config.js` 存在且 `dist/index.html` 引用它),这条链才算有验收。
4. **本产品侧的临时落地(已做,onboard-hub 仓 commit `eb611b7`)**:在业务仓 `frontend/vite.config.ts` 自建同名插件产出 `_app.config.js` 并注入 + 替换标题占位;模板修好后本处可删(或改为引用 admin-core 的插件)。
5. **验收闸固化**:静态托管类项目的上线验收必须是两层 —— ①HTTP/接口冒烟 ②**真浏览器渲染校验**(可用 company 侧 playwright-core);只跑状态码不算验收。onboard-hub 已落 `deploy/verify-render.mjs` 作为样板。

## 验收标准

- [ ] 模板仓 `examples/external-admin-web` 生产构建后,`dist/_app.config.js` 存在且含 `window._VBEN_ADMIN_PRO_APP_CONF_` 赋值,`dist/index.html` 在入口脚本之前引用它,`dist/index.html` 无 `<%=` 残留。
- [ ] 该参照工程产物用真浏览器打开:无 `pageerror`、`#app` 有子节点、页面有可见文本(附渲染截图或校验输出)。
- [ ] admin-core 的 `dist/styles/index.css` 非空(或不再依赖它),登录页在 1440×900 下容器满高(≥ 视口高)、底部版权/设置浮层**不与登录按钮重叠**(按钮中心点命中按钮自身)、普通鼠标点击可提交登录。
- [ ] 生成项目的 tailwind `content` 覆盖 **pnpm 虚拟 store**(`node_modules/.pnpm/**/node_modules/{@vben,@vben-core,@admin-template}/*/dist/**`)或改用 Vben 官方 tailwind 预设包;开箱 `pnpm build` 后产物 CSS 含 `@vben/layouts` 的工具类(`w-[34%]`、`w-2/5`、`min-h-full`),登录页呈现官方排版(左 66% 品牌面板含插画与标语 / 右 34% 表单),不是「白底 + 居中表单」。
- [ ] Vben 自定义动画工具类(`animate-float` 等)在生成项目里生效(官方 monorepo 的 `internal/tailwind-config` 需随生成物内联或由 admin-core 发布预设)。
- [ ] 生产构建冒烟含**CSS 内容断言**(取 `index.html` 引用的 CSS,判 `min-height:100%` 与 `w-[34%]` 存在),这类"HTTP 全 200 但排版塌陷"的静默回归挡在部署环节。
- [ ] 产物 CSS 里 `.min-h-full` 等 admin-core 外壳实际用到的工具类都存在(或外壳自带等价样式),不靠业务仓补丁。
- [ ] `admin-cli create` 新生成的项目,开箱 `pnpm build` 后满足上面各条(新项目不再白屏、首屏进布局、登录页不压字)。
- [ ] 菜单 `component` 字段与视图清单有机器校验(生成器写出菜单时即校验 `views/<component>.vue` 存在),杜绝"菜单点进去白屏"。
- [ ] 登录页 logo 与默认头像不再依赖公网 CDN(资产随产物自托管,断网可用);偏好里 `logo` 的层级口径写进生成器默认配置(顶层节,写错即静默回退 CDN)。
- [ ] 登录页页脚/版权按生成项目的项目名与归属覆盖,不残留模板方品牌(`Vben` + `vben.pro`)与外链。
- [ ] 未登录访问 `/` 的 redirect 参数编码正确(单次编码),登录后回跳到原目标页。
- [ ] `examples/external-admin-web` 仓内有一条可执行的产物自检(构建后跑,失败非 0 退出),纳入其常规验证流程。
- [ ] 模板仓变更记录里写明"开发态不暴露、必须生产构建 + 真渲染验收"的判据,防止后续再次只在 dev 下验。
