1
0
Files
DiAL/openspec/specs/single-executable-packaging/spec.md
lanyuanxiaoyao ccd16a583e feat: 跨平台发布打包,支持 7 个目标平台交叉编译和 tar.gz 分发
- 新增 scripts/release.ts,支持 7 个编译目标(linux/darwin/windows + musl 变体)
- 从 build.ts 提取共享构建逻辑到 build-common.ts,现有 build 行为不变
- 使用 tar-stream + node:zlib 创建 tar.gz,精确控制 Unix 权限位
- SHA256 校验和文件格式兼容 sha256sum -c
- 支持 --target 参数选择特定平台编译
- 新增 devDependency: tar-stream、@types/tar-stream
- 更新 README.md 和 DEVELOPMENT.md 文档
- 同步 openspec specs
2026-05-20 23:24:36 +08:00

92 lines
4.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## Purpose
定义将 Vite 构建的前端资源通过 code generation 嵌入 Bun 后端,打包为单个 standalone executable 的生产构建、运行配置和验证要求。
## Requirements
### Requirement: 生产构建顺序
生产构建 MUST 通过三步流水线完成Vite 前端构建 → code generation → Bun compile。
构建步骤 1-2Vite build、code generation的逻辑 SHALL 从 `scripts/build-common.ts` 导入,`scripts/build.ts` 只保留当前平台编译和编排逻辑。
#### Scenario: 运行生产构建
- **WHEN** 开发者运行生产构建命令
- **THEN** 系统 MUST 依次执行 Vite build、资源导入 code generation、Bun.build compile最终输出单可执行文件
#### Scenario: Vite 构建失败
- **WHEN** Vite build 步骤失败
- **THEN** 系统 MUST 停止后续步骤,不生成 code generation 文件或 executable
#### Scenario: Bun compile 失败
- **WHEN** Bun.build compile 步骤失败
- **THEN** 系统 MUST 清理 `.build/` 临时目录,不保留 stale executable
#### Scenario: 重构后 build 行为不变
- **WHEN** `scripts/build.ts` 改为从 `scripts/build-common.ts` 导入共享构建函数
- **THEN** `bun run build` 的产出文件路径(`dist/dial-server`)、构建步骤顺序和错误处理行为 SHALL 与重构前完全一致
### Requirement: 单 executable 输出
生产构建 SHALL 输出一个 standalone executable其中包含 Bun 后端和通过 `import with { type: "file" }` 嵌入的 Vite 前端产出。
#### Scenario: 在目标机器运行 executable
- **WHEN** 生成的 executable 在兼容目标平台上运行
- **THEN** 它 SHALL 启动全栈应用,且不要求目标机器安装 Node.js、Bun 或 `node_modules`
#### Scenario: 服务嵌入的前端
- **WHEN** executable 收到前端根路径请求
- **THEN** 它 SHALL 通过内嵌的 Vite 构建产出服务前端资源,且不需要外部 `dist/` 目录
#### Scenario: 服务嵌入 API 和页面
- **WHEN** 生成的 executable 启动,且浏览器打开前端根路径
- **THEN** 页面 SHALL 展示同一个 executable 进程中 `/api/summary``/api/targets` 返回的数据
### Requirement: 构建中间产物管理
构建流程 SHALL 使用 `.build/` 临时目录存放 code generation 产物,构建完成后清理。
清理逻辑 SHALL 定义在 `scripts/build-common.ts` 中,供 `build.ts``release.ts` 共用。
#### Scenario: 构建成功后清理中间产物
- **WHEN** 生产构建成功完成并输出 executable
- **THEN** 系统 SHALL 通过 `build-common.ts` 中的 `cleanup()` 函数删除 `.build/` 临时目录
#### Scenario: 构建失败时清理中间产物
- **WHEN** 生产构建在 Bun compile 步骤失败
- **THEN** 系统 SHALL 通过 `build-common.ts` 中的 `cleanup()` 函数删除 `.build/` 临时目录和 stale executable
### Requirement: 外部运行时配置
executable MUST 将环境相关运行时配置保留在嵌入的前端和 server bundle 之外。
#### Scenario: 修改监听端口
- **WHEN** 操作者修改受支持的 port 配置
- **THEN** 同一个 executable SHALL 在不重新构建的情况下监听新端口
#### Scenario: 缺少可选配置
- **WHEN** 可选运行时配置被省略
- **THEN** executable SHALL 使用文档化的默认值
### Requirement: 构建验证
项目 SHALL 提供 `verify` 命令执行质量检查和生产构建;原 smoke test 暂时移除executable 路由验证由后续变更重新设计。
#### Scenario: 完整验证重新构建 executable
- **WHEN** 开发者运行完整验证命令
- **THEN** 系统 MUST 先执行质量检查,再基于当前源码执行生产构建
#### Scenario: 验证失败
- **WHEN** 质量检查或构建阶段失败
- **THEN** 验证 SHALL 使命令失败
### Requirement: 生产构建版本固化
生产构建 SHALL 在 code generation 阶段读取 `package.json.version`,并将该版本号固化到生成的 production server entry 中,使 standalone executable 能在运行时返回构建时版本。
#### Scenario: 构建时注入版本号
- **WHEN** 开发者运行生产构建命令
- **THEN** 构建脚本 SHALL 在生成 `.build/server-entry.ts` 时写入当前 `package.json.version` 对应的版本字面量
#### Scenario: executable 不依赖外部 package.json 返回版本
- **WHEN** 生成的 standalone executable 在目标机器运行且外部不存在项目根目录 `package.json`
- **THEN** `GET /api/meta` SHALL 仍返回构建时固化的 `version`
#### Scenario: 升迁后重新构建
- **WHEN** 开发者先升迁 `package.json.version` 再运行生产构建命令
- **THEN** 新生成的 standalone executable SHALL 返回升迁后的版本号