feat: 迁移前端构建从 Bun fullstack 到 Vite
前端性能问题根因在于 Bun bundler 无法有效 code split、CSS
tree-shake 和产出优化的前端资源。经多轮 Bun 原生优化尝试
均无明显效果后,决定将前端构建迁回 Vite。
主要变更:
- 前端构建:从 Bun HTML import bundling 切换为 Vite build
(Rolldown code splitting、vendor chunk、CSS 优化)
- 开发模式:从 Bun fullstack 单进程 HMR 切换为 Vite dev
server + Bun API server 双进程(:5173 + :3000)
- 生产构建:三步流水线(Vite build → code generation →
Bun compile),通过 `import with { type: "file" }` 嵌入前端资源
- 静态资源服务:从 Bun HTML import manifest 切换为自定义
serveStaticAsset 函数,支持 SPA fallback 和正确的 Cache-Control
- Server 接口:BootstrapOptions 和 StartServerOptions 增加
staticAssets? 可选参数
- 文档更新:DEVELOPMENT.md 和 README.md 反映新的开发模式,
主 specs 同步 delta 变更
新增能力:
- static-asset-embedding: 构建时资源扫描与 code generation、
运行时静态资源服务
- vite-frontend-bundling: Vite 构建配置、code splitting 策略、
CSS 处理
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
## Purpose
|
||||
|
||||
定义 Bun 全栈应用运行时的 HTTP server、API 命名空间、健康检查、生产静态资源服务和 SPA fallback 行为。
|
||||
定义基于 Vite + Bun 的全栈应用运行时,包括 HTTP server、API 命名空间、健康检查、生产静态资源服务和 SPA fallback 行为。
|
||||
|
||||
## Requirements
|
||||
|
||||
@@ -64,26 +64,26 @@
|
||||
- **THEN** Bun server SHALL 返回成功的、机器可读的健康检查响应
|
||||
|
||||
### Requirement: 生产静态资源服务
|
||||
系统 SHALL 在生产模式下通过 Bun 内置的 HTML import manifest 机制服务前端资源。
|
||||
系统 SHALL 在生产模式下通过自定义 `serveStaticAsset` 函数服务嵌入的 Vite 前端产出。
|
||||
|
||||
#### Scenario: 请求构建后的资源
|
||||
- **WHEN** 客户端请求构建后的前端资源
|
||||
- **THEN** Bun server SHALL 通过 manifest 自动返回该资源并带有适当的 content type 和 content-addressable hash URL
|
||||
- **WHEN** 客户端请求 `/assets/*` 路径下的前端资源
|
||||
- **THEN** 系统 SHALL 从 StaticAssets 的 files map 中查找并返回对应资源,Content-Type 根据扩展名推断
|
||||
|
||||
#### Scenario: 请求前端根路径
|
||||
- **WHEN** 客户端请求 `/`
|
||||
- **THEN** Bun server SHALL 通过 routes 中注册的 HTML import 返回前端入口 HTML 文档
|
||||
- **THEN** 系统 SHALL 返回 StaticAssets 中的 indexHtml,Content-Type 为 `text/html; charset=utf-8`
|
||||
|
||||
### Requirement: 生产缓存策略
|
||||
系统 SHALL 利用 Bun 内置的缓存机制为生产静态资源提供缓存策略。
|
||||
系统 SHALL 为生产静态资源提供基于文件名 content hash 的缓存策略。
|
||||
|
||||
#### Scenario: 请求前端入口 HTML
|
||||
- **WHEN** 生产 Bun server 返回前端入口 HTML 文档
|
||||
- **THEN** 响应 SHALL 包含 Bun 自动生成的 ETag header
|
||||
- **WHEN** 生产 server 返回前端入口 HTML 文档
|
||||
- **THEN** 响应 SHALL 包含 `Cache-Control: no-cache` header
|
||||
|
||||
#### Scenario: 请求构建后的静态资源
|
||||
- **WHEN** 生产 Bun server 返回构建后的静态资源
|
||||
- **THEN** 响应 SHALL 包含 Bun 自动生成的 ETag header 和 content-addressable hash URL
|
||||
- **WHEN** 生产 server 返回 `/assets/*` 路径下的静态资源
|
||||
- **THEN** 响应 SHALL 包含 `Cache-Control: public, max-age=31536000, immutable` header
|
||||
|
||||
### Requirement: 低风险安全响应头
|
||||
系统 SHALL 在生产运行时的 JSON API 响应中附加低风险安全响应头;HTML 和静态资源响应由 Bun HTML import manifest 返回其内置 headers。
|
||||
@@ -92,20 +92,20 @@
|
||||
- **WHEN** 生产 Bun server 返回 `/health` 或 `/api/*` JSON 响应
|
||||
- **THEN** 响应 SHALL 包含 `X-Content-Type-Options: nosniff` 和 `Referrer-Policy` headers
|
||||
|
||||
#### Scenario: 生产 HTML 和静态资源响应使用 Bun 内置 headers
|
||||
- **WHEN** 生产 Bun server 返回前端 HTML 文档或构建后的静态资源
|
||||
- **THEN** 响应 SHALL 使用 Bun HTML import manifest 提供的内置 headers,不要求附加自定义安全 headers
|
||||
#### Scenario: 生产静态资源响应
|
||||
- **WHEN** 生产 server 返回前端 HTML 文档或构建后的静态资源
|
||||
- **THEN** 响应 SHALL 不要求附加自定义安全 headers(仅需 Content-Type 和 Cache-Control)
|
||||
|
||||
### Requirement: SPA fallback 行为
|
||||
系统 SHALL 通过 routes 中注册的 `"/*"` HTML import 通配符为非 API 路径返回前端入口 HTML 文档。
|
||||
系统 SHALL 通过 fetch fallback 为非 API、非静态资源路径返回前端入口 HTML 文档。
|
||||
|
||||
#### Scenario: 刷新前端路由
|
||||
- **WHEN** 客户端请求前端路由,例如 `/dashboard`
|
||||
- **THEN** routes 中的 `"/*"` 通配符 SHALL 返回前端入口 HTML 文档
|
||||
- **WHEN** 客户端请求不包含文件扩展名的非 API 路径(如 `/dashboard`)
|
||||
- **THEN** fetch fallback SHALL 返回前端入口 HTML 文档
|
||||
|
||||
#### Scenario: 保留 API 错误语义
|
||||
- **WHEN** 客户端请求未知的 `/api/*` 路由
|
||||
- **THEN** `/api/*` 通配符 MUST 返回 JSON 404 响应,而不是前端入口 HTML 文档
|
||||
- **THEN** routes 中的 `/api/*` 通配符 MUST 返回 JSON 404 响应,而不是前端入口 HTML 文档
|
||||
|
||||
### Requirement: 优雅关机
|
||||
系统 SHALL 在收到终止信号时正确清理资源。
|
||||
|
||||
Reference in New Issue
Block a user