feat: 引入分层配置生命周期,支持变量引用和 JSON Schema 校验

- 新增 src/server/config/ 模块(types、issues、variables、normalizer、schema)
- 配置布局从 server.host/server.port 切换为 server.listen.host/server.listen.port
- 移除 HOST/PORT 隐式环境变量覆盖,改为 YAML 显式 ${KEY} 变量引用
- 支持 ${KEY}、${KEY|default}、${KEY|}、$${KEY} 变量语法
- 使用 @sinclair/typebox + ajv 实现运行时严格契约校验和 JSON Schema 导出
- 新增 scripts/generate-config-schema.ts 和 config.schema.json
- 新增 bun run schema / schema:check 命令,check 先执行 schema:check
- 更新 README.md 和 DEVELOPMENT.md 匹配新配置体系
- 新增变量解析、schema 校验和 schema 同步测试
This commit is contained in:
2026-05-25 12:17:40 +08:00
parent 13d1fea5fb
commit c592f2b97c
20 changed files with 1169 additions and 87 deletions

View File

@@ -23,7 +23,8 @@ my-app 开发文档
src/
server/
bootstrap.ts 后端统一启动引导loadServerConfig → startServer
config.ts CLI 参数解析与配置文件加载(可选 YAML configPath支持 --help/-h
config.ts CLI 参数解析与配置文件加载 facade(可选 YAML configPath支持 --help/-h
config/ 配置解析模块types、issues、variables、normalizer、schema
dev.ts 开发模式启动入口mode: "development"
main.ts 生产模式启动入口mode: "production",安全头启用)
server.ts HTTP server 启动工厂Bun.serve routes 声明式路由 + fetch fallback 静态资源服务)
@@ -63,10 +64,11 @@ src/
time.ts 时间处理formatCountdown、formatDurationUnit、formatRelativeTime、isOlderThan、subtractHours
menu.tsx 菜单配置(路由与菜单项统一数据源)
routes.tsx 路由配置(定义所有页面路由)
scripts/
dev.ts 双进程开发服务Bun API server + Vite dev server
build.ts Vite → codegen → Bun compile 三步构建流水线(含版本号注入)
bump-version-logic.ts 纯版本管理逻辑parse、validate、bump、format
scripts/
dev.ts 双进程开发服务Bun API server + Vite dev server
build.ts Vite → codegen → Bun compile 三步构建流水线(含版本号注入)
generate-config-schema.ts 配置 JSON Schema 生成与同步校验
bump-version-logic.ts 纯版本管理逻辑parse、validate、bump、format
bump-version.ts 版本升迁 CLI 脚本
clean.ts 清理构建产物与临时文件
tests/ Bun test 测试(结构镜像 src 目录)
@@ -75,13 +77,17 @@ tests/ Bun test 测试(结构镜像 src 目录)
server/ 后端测试
bootstrap.test.ts
config.test.ts
config/ 配置模块测试
variables.test.ts
schema.test.ts
middleware.test.ts
static.test.ts
web/ 前端测试
App.test.tsx
test-utils.tsx
openspec/ OpenSpec 变更、规格文档与 fast-drive workflow schema
config.example.yaml 配置文件示例
config.example.yaml 配置文件示例server.listen 布局 + 显式变量引用)
config.schema.json 配置文件 JSON Schema由 bun run schema 生成)
```
---
@@ -188,30 +194,74 @@ export function handleMeta(mode: RuntimeMode, version: string): Response;
### 1.6 配置文件规范
配置加载流程:
配置采用分层生命周期:`unknown → AuthoringConfig → NormalizedConfig → ValidatedConfig → ServerConfig`
```
CLI argv → parseRuntimeArgs → { configPath? }
→ loadServerConfig(configPath)
可选 YAML 文件解析 → env 覆盖 → 默认值
→ ServerConfig{ host, port }
无 configPath → 默认值 { host: "127.0.0.1", port: 3000 }
有 configPath → YAML 解析 → normalize(变量替换) → strict validate → resolve → ServerConfig{ host, port }
```
配置加载流程:
1. **解析 YAML**`Bun.YAML.parse` 将配置文件解析为 `unknown`
2. **normalize**:提取 `variables`,替换 `${KEY}` / `${KEY|default}` 变量引用,移除 `variables` 段,产出 `NormalizedConfig`
3. **strict validate**:使用 Ajv + TypeBox 生成的 schema 严格校验(拒绝未知字段、校验类型和范围)
4. **resolve**:从校验后的配置中提取 `server.listen.host``server.listen.port`,填充默认值
`ServerConfig` 包含以下字段:
| 字段 | 来源 | 默认值 |
| ------ | ------------------------------------------------- | ----------- |
| `host` | `process.env["HOST"]` → YAML `server.host` → 默认 | `127.0.0.1` |
| `port` | `process.env["PORT"]` → YAML `server.port` → 默认 | `3000` |
| 字段 | 来源 | 默认值 |
| ------ | ------------------------------------------ | ----------- |
| `host` | `server.listen.host`(可含变量引用)→ 默认 | `127.0.0.1` |
| `port` | `server.listen.port`(可含变量引用)→ 默认 | `3000` |
配置文件示例(`config.example.yaml`
```yaml
# yaml-language-server: $schema=./config.schema.json
server:
host: "127.0.0.1"
port: 3000
listen:
host: "${HOST|127.0.0.1}"
port: ${PORT|3000}
```
变量语法:
| 语法 | 说明 |
| --------------- | ------------------------------ |
| `${KEY}` | 引用变量,未定义时报错 |
| `${KEY\|value}` | 引用变量,未定义时使用默认值 |
| `${KEY\|}` | 引用变量,未定义时使用空字符串 |
| `$${KEY}` | 转义,输出 `${KEY}` 原文 |
变量解析优先级:`variables 字段``process.env``默认值``unresolved 报错`
完整变量引用保留原始类型,部分拼接转为 string。环境变量不会隐式覆盖配置。
配置模块结构(`src/server/config/`
| 文件 | 职责 |
| --------------------- | -------------------------------------------------------- |
| `types.ts` | AuthoringConfig、NormalizedConfig、ValidatedConfig 类型 |
| `issues.ts` | 结构化配置问题、路径渲染、去重、中文格式化 |
| `variables.ts` | 变量提取、引用解析、默认值、环境变量查找、类型推断 |
| `normalizer.ts` | Authoring → Normalized 转换(变量替换 + 移除 variables |
| `schema/fragments.ts` | TypeBox schema 片段 |
| `schema/builder.ts` | Authoring/Normalized schema 构建 |
| `schema/validate.ts` | Ajv strict 校验 + 错误映射 |
| `schema/export.ts` | JSON Schema 导出(用于生成 config.schema.json |
JSON Schema 相关命令:
```bash
bun run schema # 重新生成 config.schema.json
bun run schema:check # 校验 config.schema.json 是否同步
```
运行时依赖 `@sinclair/typebox`JSON Schema 类型构建)和 `ajv`JSON Schema 校验),用于配置启动时严格契约校验。
### 1.7 版本管理
项目使用 `package.json.version` 作为版本号唯一来源,严格 `MAJOR.MINOR.PATCH` 格式。
@@ -573,11 +623,9 @@ bun run verify
### 3.6 环境变量
| 变量 | 用途 | 默认值 |
| --------------------------- | ----------------------------------------------- | ----------- |
| `BUN_TARGET`/`BUILD_TARGET` | 交叉编译目标平台(仅在 `bun run build` 时有效) | 当前平台 |
| `HOST` | 服务监听地址 | `127.0.0.1` |
| `PORT` | 服务监听端口 | `3000` |
| 变量 | 用途 | 默认值 |
| --------------------------- | ----------------------------------------------- | -------- |
| `BUN_TARGET`/`BUILD_TARGET` | 交叉编译目标平台(仅在 `bun run build` 时有效) | 当前平台 |
### 3.7 项目配置文件
@@ -590,7 +638,8 @@ bun run verify
| `.prettierrc.json` | Prettier 格式化规则(`printWidth: 120` |
| `.prettierignore` | Prettier 排除路径 |
| `.lintstagedrc.json` | lint-staged 配置TS/TSX → ESLintMD/JSON/YAML → Prettier |
| `config.example.yaml` | 配置文件示例 |
| `config.example.yaml` | 配置文件示例server.listen 布局 + 显式变量引用) |
| `config.schema.json` | 配置文件 JSON Schema由 bun run schema 生成) |
| `vite.config.ts` | Vite 构建配置React 插件、代码分割、API proxy |
| `bunfig.toml` | Bun 配置(测试 preload、排除规则 |
| `opencode.json` | OpenCode 工具配置 |
@@ -624,8 +673,10 @@ bun run verify
bun run lint # ESLint 检查含类型感知规则、导入排序、导入验证、Prettier 格式)
bun run format # Prettier 自动格式化
bun run typecheck # TypeScript 类型检查
bun run schema # 生成 config.schema.json
bun run schema:check # 校验 config.schema.json 是否同步
bun test # 运行所有测试
bun run check # 一键运行 typecheck + lint + test
bun run check # 一键运行 schema:check + typecheck + lint + test
bun run verify # 完整验证check + build
```
@@ -735,4 +786,5 @@ bun run verify # 完整验证check + 构建)
- 当前仅为单页面应用,不涉及用户认证和权限控制
- 不支持集群部署,单进程运行
- 配置文件仅支持 YAML 格式,不支持热加载
- 变量替换范围仅限 `server` 子树
- 无国际化和多语言支持