3213d4c718
- 重构架构:抽离AddCloudSyncServer到扩展类,补全中间层文档对齐 - 修复根路径404与鉴权跳转:新增中间件处理浏览器请求302跳转 - 实现种子数据初始化:添加默认管理员账号自动创建逻辑 - 优化前端代理与构建:新增Vite代理配置与自动构建Target - 补全测试与文档:新增集成测试,更新开发与部署文档
7.6 KiB
7.6 KiB
研发工单 v1.3.0 - 06:Web 端根路径托管前端
术语澄清:本文件中"研发工单"指智能体/开发者执行的编码工作项,与业务侧的 Todo 待办项无关。详见 .trae/rules/全局/04-研发工单全流程规范.md。
一、背景与动机
根据 01-项目架构.md §3「模式 B:Web 端」端点划分表的定义:
| URL 前缀 | 内容 | 来源 |
|---|---|---|
/(根路径) |
Hua.Todo.Web 用户前端(登录后 Todo 列表) | src/Hua.Todo.Web 的 dist/ 构建产物,复制到 Hua.Todo.Host/wwwroot/ |
/api/* |
动态 API | DynamicApi |
/admin/* |
管理后台前端 | Hua.Todo.Host/wwwroot/admin/(占位) |
当前代码不符合:
- Host
Program.cs没有UseStaticFiles()/UseDefaultFiles();访问http://localhost:5173/返回 404 Hua.Todo.Host.csproj没有任何构建 Target 把Hua.Todo.Web的dist/*产物拷到Hua.Todo.Host/wwwroot/- 开发联调文档缺失:开发时 Vite(:5174)+ Host(:5173)双开怎么跑、端口怎么代理、生产部署怎么构建单文件,都没有书面说明
结果:用户按规则部署"Web 端(Hua.Todo.Host)",会拿到一个只有 API 没有前端页面的半成品服务。本工单补全模式 B 的生产/开发闭环。
二、目标 / 范围
2.1 做什么
- Host 侧 ASP.NET Core 中间件补齐:在
Program.csDynamicApi 之前插入UseDefaultFiles()+UseStaticFiles(),并保证 SPA 路由(前端内部路由,如/settings)fallback 到index.html(用MapFallbackToFile("index.html")) - Host csproj 构建 Target:新增
npm install(若node_modules不存在)+npm run build(Hua.Todo.Web)+ 复制dist/**→$(OutputPath)/wwwroot/的 MSBuild Target,只在构建 Host 时触发(确保dotnet publish Hua.Todo.Host产出含前端的完整包) - 开发环境联调说明:在
docs/manual/08-构建与开发指南.md(或现有的开发指南对应章节)追加 "模式 B(Web 端)开发双开步骤" 与 "生产发布步骤" 小节 - 验收测试:新增 1 个 Host 集成测试(
WebRootStaticFileTests),验证 HTTP GET/返回 200 且 body 含<title>/<div id="app">特征
2.2 不做什么
- 不实现
/admin/*管理后台前端(只有 index.html 占位,v1.2.0 工单 06.1 规划) - 不改嵌入式模式 MAUI/Avalonia 的前端托管逻辑(那边是
EmbeddedWebServerService内自己 UseWebRoot + 复制 wwwroot,与 Host 部署模式解耦) - 不改 Hua.Todo.Web 构建逻辑本身(只调用现成
npm run build;不修改 vite.config.ts build.outDir)
三、前置条件 / 依赖
- v1.3.0 工单 05 缺口 D:
CloudSyncEndpointExtensions.cs的还原落地(因为本工单需要在 Program.cs 末尾追加MapFallbackToFile,和MapCloudSyncProxySettings()同时存在于Program.cs尾部,改动顺序不敏感但建议先落 05 的 D) - Node.js + npm 在构建机器可用(作为前置条件,Host csproj Target 不负责安装 Node)
- 共享文件:
Hua.Todo.Host/Program.cs、Hua.Todo.Host/Hua.Todo.Host.csproj、docs/manual/08-构建与开发指南.md - 可与 v1.3.0 工单 03、05 并行
四、验收标准(Given-When-Then)
| # | 场景 | GIVEN | WHEN | THEN |
|---|---|---|---|---|
| 1 | 根路径返回前端 HTML(模式 B) | Host 已 dotnet build,且 wwwroot/index.html 有内容 |
HTTP GET http://localhost:5173/ |
返回 200;Content-Type: text/html;body 含 <div id="app">(来自 Hua.Todo.Web 模板/index.html) |
| 2 | SPA 路由 fallback | 同 1 | HTTP GET http://localhost:5173/settings(前端内部路由) |
返回 200;body 是 index.html 全文,不是 404 页 |
| 3 | API 路由不被 fallback 覆盖 | 同 1 | HTTP POST /api/cloud-sync/probe |
DynamicApi 正常处理(200 / 503 都行,但不是 index.html) |
| 4 | MSBuild Target:dotnet publish Hua.Todo.Host |
干净克隆(删 node_modules 和 dist),Node 已装 | 执行 dotnet publish src/Hua.Todo.Host -c Release -o ./publish-host |
publish-host/wwwroot/ 下有 index.html、assets/ 等 Hua.Todo.Web build 产物;且 publish-host 启动后 GET / 满足验收 1 |
| 5 | MSBuild Target 增量构建(不重复 npm run build) | Hua.Todo.Web src 文件未变动,已执行过一次 build | 再次执行 dotnet build src/Hua.Todo.Host |
npm build 阶段跳过后直接 copy(Inputs/Outputs 正确);日志出现 "Skipping target BuildHuaTodoWeb"(或等价跳过提示) |
| 6 | 开发联调(文档可执行) | 新环境 clone 后 Node 已装、.NET 10 SDK 已装 | 按 docs/manual 新增章节的步骤执行(两条命令:1. Vite dev;2. Host run) | Vite :5174 页面打开、API 请求能到 Host :5173;云同步探测能返回 isReachable JSON(与 307 修复后的链路一致) |
五、并行冲突规避
| Touch List | 共享文件策略 | 编译绿线策略 |
|---|---|---|
Hua.Todo.Host/Program.cs |
只在 app.UseDynamicApi(); 之前插入 UseDefaultFiles/UseStaticFiles;在 app.Run() 之前追加 MapFallbackToFile("index.html")(若已存在 /api/cloud-sync/proxy-settings endpoint 则不改动) |
dotnet build Hua.Todo.Host.csproj 0 错误 |
Hua.Todo.Host/Hua.Todo.Host.csproj |
追加 <Target Name="BuildHuaTodoWebWebRoot" BeforeTargets="BeforeBuild" ...> 节点;不修改任何现有 PropertyGroup/ItemGroup/Target |
同编译 + dotnet publish 产出验证 |
docs/manual/08-构建与开发指南.md |
末尾追加两个新小节标题,不改原有章节顺序 | 纯 Markdown |
test/Hua.Todo.Host.Tests/... |
新建 WebRootStaticFileTests.cs(独立文件),不修改既有测试类 |
dotnet test Hua.Todo.Host.Tests 新增 + 既有全部通过 |
六、风险与回滚
| 风险 | 影响 | 应对策略 |
|---|---|---|
npm install 时长慢(首次)+ 网络差导致构建失败 |
CI publish 超时 | MSBuild Target 加 ContinueOnError="WarnAndContinue" + 清晰错误日志:"Hua.Todo.Web build skipped,deploy wwwroot 是空的——请手动构建 Hua.Todo.Web 后重试" |
MapFallbackToFile 顺序放错,覆盖掉 /api/* 或 /swagger/* |
API / Swagger 404 | 在 Program.cs 写明确顺序:UseSwagger → UseStaticFiles → UseAuthentication/Authorization → UseDynamicApi → MapMcpServer → MapFallbackToFile;并在集成测试里同时验证 fallback 和 API 都正常 |
| 增量构建 Inputs/Outputs 写粗了导致漏 build(或反复 build) | 前端代码变更后不生效 / 构建变慢 | Inputs 精确到 Hua.Todo.Web/package.json + Hua.Todo.Web/src/**/*.{ts,vue,css,html};Outputs 精确到 wwwroot/index.html |
| CI 环境 Node 不存在 | 构建报错 | Target 检测不到 node/npm 时仅 Warning,不阻塞 Host API 层 build(生产环境可由外部 CI 先 build 前端再打包) |
七、与其他工单的语音/UI 入口衔接
按 05-多入口功能同步规范.md 第 3.2 条:纯基础设施调整无需检查双入口。
| 入口 | 已规划 | 方案 |
|---|---|---|
| UI | ✅(本次就是 UI 托管入口补齐) | 模式 B http://localhost:5173/ 直接返回 Hua.Todo.Web |
| 语音 | ❌(无需) | 不涉及业务操作 |
创建日期:2026-08-08 关联规则:01-项目架构.md §3 模式 B 关联工单:v1.3.0 工单 05;v1.2.0 工单 06.1(Admin 管理后台前端)