1
0
Files
DiAL/DEVELOPMENT.md
lanyuanxiaoyao a5cf6065c2 chore: 强化代码质量与风格检查体系
ESLint 升级到 recommended-type-checked + stylistic-type-checked,
引入 perfectionist 导入排序和 import 插件导入验证。

Prettier 显式声明全部格式化参数,消除跨环境差异。
TypeScript 启用 noUnusedLocals 和 noPropertyAccessFromIndexSignature。
完善 ignore 列表,排除 .agents/、bun.lock、data/ 等。
引入 husky + lint-staged(pre-commit)+ commitlint(commit-msg)。
更新 DEVELOPMENT.md 代码质量章节。
修复所有新增规则检测到的类型和风格违规。
2026-05-12 18:44:59 +08:00

31 KiB
Raw Blame History

DiAL 开发文档

本文档面向 DiAL 项目的开发者,介绍项目结构、构建流程、测试、代码规范等内容。

用户使用说明请参阅 README.md

目录


项目结构

src/
  server/
    app.ts          Bun HTTP 路由入口(路由分发 + API 汇聚)
    config.ts       CLI 参数解析
    dev.ts          生产/开发启动入口
    server.ts       HTTP server 启动工厂
    helpers.ts      共享响应格式化工具jsonResponse、createHeaders 等)
    middleware.ts   API 参数校验中间件guardGetHead、validateTargetId 等)
    static.ts       静态资源服务与 SPA fallback
    routes/         API 路由 handler按端点拆分
      health.ts     GET /health
      summary.ts    GET /api/summary
      targets.ts    GET /api/targets
      history.ts    GET /api/targets/:id/history
      trend.ts      GET /api/targets/:id/trend
    checker/
      types.ts          类型定义
      config-loader.ts  YAML 配置解析与校验
      store.ts          SQLite 数据存储
      engine.ts         调度引擎(按 interval 分组的 es-toolkit groupBy + Semaphore 并发控制)
      size.ts           大小单位解析
      runner/           Checker 统一抽象与注册机制
        types.ts          Checker 接口、CheckerContext、ResolveContext
        registry.ts       CheckerRegistry 注册中心
        index.ts          注册入口registerCheckers
        shared/           共享 expect 断言函数(跨 checker 复用)
          failure.ts      失败信息类型
          operator.ts     操作符系统applyOperator、evaluateJsonPath
          duration.ts     耗时断言
          text.ts         文本规则断言
          body.ts         Body 规则断言JSONPath/XPath/CSS/contains/regex
        http/             HTTP Checker 子包
          runner.ts        HttpCheckerresolve/execute/serialize
          expect.ts        HTTP 专用断言status/headers
        command/          Command Checker 子包
          runner.ts        CommandCheckerresolve/execute/serialize
          expect.ts        Command 专用断言exitCode
  shared/
    api.ts          前后端共享 TypeScript 类型
  web/              Vite + React 前端 Dashboard
    components/     UI 组件表格、分组、Drawer、状态条等
    constants/      常量定义(列配置、类型映射、排序/筛选/颜色阈值函数)
    hooks/          TanStack Query 数据层useTargetDetail 集成轮询/条件查询)
    utils/          前端工具函数
scripts/            开发、构建和 smoke test 脚本
tests/              Bun test 测试
openspec/           OpenSpec 变更与规格文档

前后端边界

前端只通过 HTTP 调用后端API 路径为 /api/*。共享类型放在 src/shared,前端不得 import src/server 的运行时实现。


一、后端开发指引

1.1 架构概览

启动流程:
  dev.ts → readRuntimeConfig(cli args) → loadConfig(yaml)
  → ProbeStore(db) → ProbeEngine(store, targets) → startServer(store)

运行时:
  定时器(tick) → ProbeEngine.probeGroup()
  → HTTP: fetcher.ts / Command: command-runner.ts
  → runner/*/expect.ts 校验 → store.insertCheckResult()

HTTP 请求:
  Request → app.ts(路由分发) → routes/*.ts(handler)
  → middleware.ts(参数校验) → helpers.ts(响应格式化) → Response

1.2 库使用优先级

后端代码开发遵循严格的库选择顺序:

优先级 来源 典型用途
1 Bun 内置 API Bun.servebun:sqliteBun.spawnBun.fileBun.YAML
2 es-toolkit 类型判断(isPlainObject/isNil/isEmptyObject)、深度比较(isEqual)、错误判断(isError)、并发控制(Semaphore)、集合操作(groupBy
3 标准 Web API Object.fromEntriesHeadersfetchAbortController
4 主流三方库 cheerioHTML 解析、xpath + @xmldom/xmldomXML 解析)
5 自行实现 仅在以上都无法满足时(如 parseDurationparseSizeevaluateJsonPath 等专项逻辑)

原则:新增依赖前先检查上述每一层级是否已有可用方案。禁止随意引入新依赖。

1.3 API 路由开发

路由文件位于 src/server/routes/每个端点一个文件。handler 函数签名统一为:

export function handleXxx(params, store: ProbeStore, method: string, mode: RuntimeMode): Response;

请求处理流程

  1. app.tscreateFetchHandler 作为总入口,根据 URL pattern 匹配路由
  2. API 路由统一经过 guardGetHead 做方法检查(仅允许 GET/HEAD
  3. 各 handler 内部通过 middleware.ts 提供的 validateTargetIdvalidateTimeRangevalidatePagination 做参数校验
  4. 校验函数返回 Response 表示校验失败(直接返回),返回数据对象表示通过
  5. 业务逻辑通过 store 查询数据,用 helpers.tsjsonResponsemapCheckResultformatDuration 等格式化输出

新增路由步骤

  1. src/server/routes/ 下创建 <name>.ts
  2. 实现 handler 函数并 export
  3. app.tscreateFetchHandler 中注册路径匹配和调用
  4. tests/server/app.test.ts 中添加对应测试

1.4 共享工具

  • helpers.ts:跨路由共用的响应工具函数(jsonResponsecreateHeaderscreateApiErrormapCheckResultformatDurationcreateHealthResponse
  • middleware.tsAPI 参数校验函数(guardGetHeadvalidateTargetIdvalidateTimeRangevalidatePagination
  • static.ts:生产模式下的静态资源服务与 SPA fallback

1.5 类型定义规范

  • 共享类型src/shared/api.ts 为唯一源头,前后端共同引用
  • 前端不得 import src/server/ 下的任何文件
  • 严格联合类型优先于宽类型:如 phase: "status" | "duration" | ... 而非 phase: string
  • 后端内部扩展checker/types.tsCheckResult 通过 extends 共享版本的 ApiCheckResult 增加 targetName 等内部字段
  • 存储层类型(StoredTargetStoredCheckResult)独立定义,与 API 类型分离
  • 配置类型(ProbeConfigTargetConfig)支持 discriminated union通过 type 字段区分 http/command

1.6 数据存储规范

基于 bun:sqliteWAL 模式运行,数据库文件位于配置的 dataDir 下。

Statement 使用规范

场景 方式 原因
单次读/写 this.db.query(sql).get()/all()/run() bun:sqlite 内置 statement 缓存,自动复用
事务内多次复用 this.db.prepare(sql) 缓存为局部变量 事务闭包中需要持有引用

查询优化

  • 避免 N+1 查询:批量场景优先用单次 SQL 聚合GROUP BY、子查询 JOIN+ 内存组装
  • 新增批量查询方法时必须编写对应单元测试
  • getSummary()GET /api/targets 的响应组装已通过 getLatestChecksMap + getAllTargetStats 实现批量查询

Schema

  • targetsnameUNIQUE、type、target展示摘要、configJSON、interval_ms、timeout_ms、expectJSON、grp
  • check_resultstarget_idFK CASCADE、timestamp、matched0/1、duration_ms、status_detail、failureJSON
  • 复合索引:(target_id, timestamp)

1.7 拨测引擎

  • 调度ProbeEnginees-toolkit/groupBy 按 interval 分组,每组独立 setInterval 定时触发
  • 并发控制es-toolkit/Semaphore 限制全局最大并发数(maxConcurrentChecksacquire() 阻塞等待
  • Runner 选择engine.runCheck()target.type 分发到 runHttpCheckrunCommandCheck
  • 超时控制HTTP 用 AbortControllerCommand 用 setTimeout + proc.kill()
  • 结果写入:检查结果通过 store.insertCheckResult() 写入 SQLiteengine 通过 targetNameToId 缓存 name→id 映射
  • 生命周期start()/stop() 管理定时器,stop() 清理所有 setInterval

1.8 expect 断言系统

两层模型:观测值收集规则校验

HTTP 校验流程

runHttpCheck → 收集观测(statusCode/headers/body/durationMs)
→ checkHttpExpect → status → duration → headers → body(可选)
→ 首个失败即停止,返回 CheckFailure

Command 校验流程

runCommandCheck → 收集观测(exitCode/stdout/stderr/durationMs)
→ checkCommandExpect → exitCode → duration → stdout → stderr
→ 首个失败即停止

Body 规则类型

  • contains:文本包含匹配
  • regex:正则表达式匹配
  • jsonJSONPath 提取 + 操作符比较(使用 es-toolkit/isPlainObject 区分纯值和操作符)
  • csscheerio CSS 选择器 + 操作符比较
  • xpathXPath 节点提取 + 操作符比较

操作符equals(深度比较,es-toolkit/isEqual)、containsmatch(正则)、emptyisNil+isEmptyObject)、existsgte/lte/gt/lt

1.9 错误模式

  • API 错误{ error: "描述", status: <code> },状态码 400/404/405/503
  • CheckFailure{ kind: "error"|"mismatch", phase, path, expected?, actual?, message }
  • 错误处理expect 校验失败记录首个失败原因;网络/超时/进程崩溃统一为 kind:"error"
  • 日志:解析失败等非致命异常用 console.warn,启动失败用 console.error + process.exit(1)

1.10 测试规范

  • 测试文件与源文件对应:tests/server/checker/runner/shared/body.test.tssrc/server/checker/runner/shared/body.ts
  • 使用 bun:test 框架(describe/test/expect),测试数据库用临时目录 + tmpdir()
  • 新增 store 方法必须编写单元测试;新增 API 端点必须在 app.test.ts 中添加集成测试
  • 测试后清理:afterAllstore.close() + rm(tempDir, { recursive: true })

二、前端开发指引

2.1 技术栈概览

层面 技术 用途
框架 React 19 UI 组件开发
构建 Vite 8 开发服务与生产构建
语言 TypeScript 6 类型安全
UI 库 TDesign React + tdesign-icons-react UI 组件与图标
数据层 TanStack Query (React Query) 服务端状态管理与自动轮询
图表 Recharts 拨测趋势折线图与状态环状图
路由 无(单页面 Dashboard 仅需 Drawer/Tab 做页面内导航

不引入的依赖React Router单页面场景不需要、状态管理库TanStack Query 即服务端状态层,组件内用 useState 足够)

2.2 组件树与数据流

main.tsx
└── QueryClientProviderTanStack Query 全局挂载)
    └── App根组件
        ├── SummaryCards总览统计卡片
        │   └── useSummary() ─── GET /api/summary8s 轮询)
        └── TargetBoard目标列表
            ├── useTargets() ─── GET /api/targets8s 轮询)
            └── TargetGroup[](按 group 字段分组)
                └── PrimaryTable ← TARGET_TABLE_COLUMNS列定义排序/筛选/渲染)
        └── TargetDetailDrawer目标详情抽屉
            └── useTargetDetail() ── 按需发起 trend + history 查询
                ├── Tab: 概览 → Statistic + TrendChart + StatusDonut + Descriptions
                └── Tab: 记录 → PrimaryTable分页历史记录

数据层架构

hooks/useTargetDetail.ts唯一的数据层入口
├── queryKeys结构化 query key确保缓存粒度精确
├── useSummary() → /api/summary8s 自动轮询)
├── useTargets()  → /api/targets8s 自动轮询)
└── useTargetDetail()(组合 hook管理 Drawer 全部状态)
    ├── 内部复用 useTargets() 的缓存来查找 selectedTarget
    ├── useQuery(/api/targets/:id/trend)条件查询enabled 仅当 Drawer 打开且时间范围有效)
    └── useQuery(/api/targets/:id/history)(条件查询:含分页)

2.3 TanStack Query 数据层

Query Key 规范

const queryKeys = {
  summary: () => ["summary"] as const,
  targets: () => ["targets"] as const,
  trend: (targetId: number, from: string, to: string) => ["trend", targetId, from, to] as const,
  history: (targetId: number, from: string, to: string, page: number) => ["history", targetId, from, to, page] as const,
};
  • Key 使用 structured array(非字符串),以便精确匹配和按 prefix 失效
  • 使用 as const 保持字面量类型
  • 排序scope → id → 参数(粒度从粗到细)

查询配置规范

// 全局面板级查询(需要持续刷新)
useQuery({
  queryKey: queryKeys.summary(),
  queryFn: () => fetchJson<SummaryResponse>("/api/summary"),
  refetchInterval: 8000, // 自动轮询间隔
  refetchIntervalInBackground: false, // 切后台不轮询
});

// 详情级查询(按需加载)
useQuery({
  queryKey: selectedTargetId ? queryKeys.trend(id, from, to) : ["trend", "disabled"],
  queryFn: () => fetchJson(`/api/targets/${id}/trend?...`),
  enabled: selectedTargetId !== null && !!timeFrom && !!timeTo, // 条件查询
});

fetch 封装

async function fetchJson<T>(url: string): Promise<T> {
  const response = await fetch(url);
  if (!response.ok) throw new Error(`HTTP ${response.status}`);
  return response.json() as Promise<T>;
}
  • 统一使用 fetch(不引入 axios与后端共享 Web API 生态
  • 错误抛异常,由 TanStack Query 的 error 状态承接

QueryClient 全局配置

new QueryClient({
  defaultOptions: {
    queries: {
      retry: 1, // 失败重试 1 次
      refetchOnWindowFocus: true, // 窗口聚焦时刷新
      staleTime: 5000, // 5s 内视为 fresh避免重复请求
    },
  },
});

2.4 组件开发规范

文件命名与导入

  • 每个 React 组件一个 .tsx 文件,文件名使用 PascalCaseStatusDot.tsx
  • 组件 props 定义为 interface XxxProps,紧邻组件函数声明
  • 类型从 ../../shared/api 导入,使用 type 导入(import type { ... }
import type { TargetStatus } from "../../shared/api";
import { StatusDot } from "./StatusDot";

interface TargetGroupProps {
  name: string;
  targets: TargetStatus[];
  onTargetClick: (target: TargetStatus) => void;
}

export function TargetGroup({ name, targets, onTargetClick }: TargetGroupProps) {
  // ...
}

组件拆分原则

  • 展示组件components/):纯渲染逻辑,通过 props 接收数据,通过回调返回事件
  • 容器逻辑放在 hooks 中,组件只做数据消费
  • 常量数据(列定义、排序器、筛选器)放在 constants/,不放在组件内部
  • 工具函数(时间处理等)放在 utils/,保持纯函数无副作用

现有组件清单

组件 文件 用途
App app.tsx 根组件,编排全局状态与布局
SummaryCards components/SummaryCards.tsx 总览统计卡片(全部/正常/异常)
TargetBoard components/TargetBoard.tsx 按分组渲染目标表格列表
TargetGroup components/TargetGroup.tsx 单个分组标题 + PrimaryTable
TargetDetailDrawer components/TargetDetailDrawer.tsx 目标详情抽屉(概览/记录 Tab
TrendChart components/TrendChart.tsx Recharts 双轴折线图(耗时/可用率)
StatusDonut components/StatusDonut.tsx Recharts 环状图UP/DOWN 分布)
StatusDot components/StatusDot.tsx 圆形状态指示点(绿/红)
StatusBar components/StatusBar.tsx 最近采样状态条(多色块)
GroupHeader components/GroupHeader.tsx 分组标题(名称 + 统计)

2.5 新增功能开发步骤

以"新增一个详情页面 Tab"为例:

  1. 确认数据需求:是已有 API 数据还是需要新端点?
    • 如有新端点,先在 src/server/routes/ 添加,参考 1.3 新增路由步骤
    • 如有新字段,更新 src/shared/api.ts 类型定义
  2. 实现 hooks:在 src/web/hooks/useTargetDetail.ts 中新增 useQuery(写好 queryKeyenabled 条件)
  3. 编写组件:在 src/web/components/ 创建组件文件
    • TargetDetailDrawer.tsx 中新增 <Tabs.TabPanel> 引用
  4. 编写常量:如有列定义/排序器/筛选器,放在 src/web/constants/
  5. 编写测试:在 tests/web/ 下添加对应的单元测试

2.6 样式开发规范

前端基于 TDesign React 构建 UI样式开发遵循以下优先级从高到低

  1. 使用 TDesign 组件:布局、间距、排版优先使用 TDesign 组件(如 Space、Divider、Typography
  2. 使用 TDesign 组件 props:通过组件的 props 参数控制外观(如 themevariantsize
  3. 使用 TDesign CSS tokens:颜色、间距、字体等使用 --td-* CSS 变量(如 --td-success-color--td-comp-margin-xxl
  4. 在 styles.css 中定义 CSS 类:无法通过上述方式满足的样式需求,集中定义在 styles.css
  5. 自行开发组件:仅在 TDesign 无法满足需求时自行开发

红线

  • 严禁在组件中使用 style 属性内联调整样式
  • 严禁通过 CSS 覆盖 TDesign 组件内部类名(如 .t-tab-panel),如需定制使用组件的 className prop
  • 严禁使用 !important
  • 颜色统一使用 TDesign CSS tokens--td-success-color--td-error-color--td-warning-color 等),不使用硬编码色值

styles.css 组织

  • 自定义 CSS 变量(如可用率渐变色 --avail-0 ~ --avail-9)定义在 :root
  • 布局类(.dashboard.dashboard-header)定义全局页面结构
  • 组件修饰类(.status-dot--up.latency-ok)为自定义视觉组件提供样式变体
  • TDesign 表格行高亮(.row-down)通过 rowClassName prop 应用

2.7 前端测试规范

  • 测试目录:tests/web/,结构对应 src/web/
  • 重点测试 constants/ 中的纯函数(排序器、筛选器、颜色阈值等)
  • 使用 bun:test 框架

三、项目运行、集成与打包

3.1 开发期运行

同时启动前后端

bun run dev probes.yaml

scripts/dev.ts 通过 Bun.spawn 同时启动两个子进程:

bun run dev probes.yaml
├── bun run dev:server probes.yaml  → Bun HTTP 后端(默认 3000 端口)
└── bun run dev:web                 → Vite 前端开发服务器5173 端口)
  • 任一子进程退出会导致整体退出
  • SIGINT/SIGTERM 信号会同时终止两个子进程
  • BACKEND_PORT 环境变量可覆盖后端端口

分别启动

# 启动后端(含 watch 模式自动重启)
bun run dev:server probes.yaml

# 另开终端启动前端
bun run dev:web

3.2 前后端集成方式

开发期代理

Vite 配置了开发代理(vite.config.ts

server: {
  proxy: {
    "/api": {
      target: `http://127.0.0.1:${backendPort}`,
      changeOrigin: true,
    },
  },
}

前端访问 /api/*Vite 开发服务器自动转发到后端 http://127.0.0.1:${backendPort},无需 CORS 配置。

前端开发地址为 http://127.0.0.1:5173(严格端口 strictPort: true)。

后端在开发模式下不提供静态资源服务,访问 http://127.0.0.1:3000 会提示"请通过 Vite 前端地址访问"。

生产期集成

生产可执行文件是单体应用:前端静态资源嵌入 binary后端同时提供 API 和静态文件服务。

./dist/dial-server probes.yaml

启动后:
  访问 http://127.0.0.1:3000/        → 返回前端 SPAindex.html
  访问 http://127.0.0.1:3000/api/*   → 返回后端 API
  访问 /assets/*                     → 返回带不可变缓存的静态资源

SPA fallback 逻辑(src/server/static.ts

  • / → index.html
  • 匹配 /assets/* → 返回对应文件(未匹配则 404
  • 其他路径(如 /dashboard)→ fallback 到 index.htmlSPA 路由)

3.3 构建打包

构建命令

bun run build

构建流程详解

scripts/build.ts 执行以下步骤:

1. vite build
   ├── 入口src/web/index.html
   └── 输出dist/web/index.html + assets/

2. 生成 .build/static-assets.ts临时文件
   ├── import Vite 产物为 Bun.file
   └── 导出 staticAssets: StaticAssets 对象

3. 生成 .build/server-entry.ts临时文件
   └── import 后端入口模块 + staticAssets作为 Bun.build 入口

4. Bun.build({ compile, minify, sourcemap: "linked" })
   └── 输出dist/dial-server单文件可执行 binary

产物

产物 用途
dist/dial-server 生产可执行文件
dist/web/ Vite 构建产物(中间产物)
.build/ 临时生成文件(构建后清理)

构建参数

环境变量 说明
BUN_TARGET/BUILD_TARGET 交叉编译目标平台(如 bun-linux-x64

运行可执行文件

./dist/dial-server probes.yaml

清理

bun run clean
# 清理 .build/ 缓存和 *.bun-build 临时文件

3.4 开发工作流

日常开发循环

bun run dev probes.yaml    # 启动开发环境
# 修改代码 → Vite HMR前端/ bun --watch后端自动重启
bun run check              # 提交前运行完整质量检查

完整验证流程

bun run verify
# = bun run check + bun run build + bun run test:smoke

verify 适合 CI 或正式提交前会完整验证类型检查、lint、格式、单元测试、构建、smoke test。

3.5 Smoke Test

bun run test:smoke

scripts/smoke.ts 构建后验证流程:

  1. 动态分配空闲端口
  2. 用临时配置文件启动 dist/dial-server
  3. 等待健康检查通过
  4. 验证所有 API 端点返回正确数据
  5. 验证静态资源服务(含 SPA fallback 和 404 处理)
  6. 验证安全 headers
  7. 测试结束清理临时目录和进程

3.6 脚本说明

脚本 文件 说明
bun run dev scripts/dev.ts 同时启动前后端开发服务
bun run build scripts/build.ts Vite 构建 + Bun 编译可执行文件
bun run test:smoke scripts/smoke.ts 构建后的端到端验证
bun run clean scripts/clean.ts 清理构建缓存与临时文件

3.7 环境变量

变量 用途 默认值
PORT/BACKEND_PORT 后端监听端口(开发期 Vite 代理目标、生产期监听端口) 3000
BUN_TARGET/BUILD_TARGET 交叉编译目标平台(仅在 bun run build 时有效) 当前平台

3.8 项目配置文件

文件 用途
package.json 项目信息、脚本、依赖声明
tsconfig.json TypeScript 配置ESNext 模块、严格模式)
vite.config.ts Vite 开发代理与构建配置
eslint.config.js ESLint 规则(含前端不得 import server 的检查)
.prettierrc.json Prettier 格式化规则(printWidth: 120
.prettierignore Prettier 排除路径
probes.example.yaml 配置文件示例
opencode.json OpenCode 工具配置TDesign MCP server

3.9 依赖管理

  • 包管理器:仅使用 bun,禁止使用 npm、pnpm、yarn
  • 安装依赖bun install
  • 运行工具:使用 bunx,禁止使用 npxpnpx
  • 锁文件bun.lock

3.10 目录约定

目录 约定
src/server/ 后端代码,不能 import src/web/
src/web/ 前端代码,不能 import src/server/
src/shared/ 前后端共享类型,双向可引用
scripts/ 独立运行脚本,可 import 项目源码
tests/ 测试目录,结构镜像 src 目录
dist/ 构建产物gitignore
.build/ 构建临时文件gitignore
openspec/ OpenSpec 变更管理与规格文档
data/ 默认数据目录gitignore运行期生成 SQLite

代码质量

项目使用多层代码质量保障体系ESLint 类型感知规则 + Perfectionist 导入排序 + Prettier 格式化 + TypeScript 严格模式 + Git hooks 自动化。

bun run lint          # ESLint 检查(含类型感知规则、导入排序、导入验证)
bun run format:check  # Prettier 格式检查
bun run format        # Prettier 自动格式化
bun run typecheck     # TypeScript 类型检查(含 noUnusedLocals、noPropertyAccessFromIndexSignature
bun test              # 运行所有测试
bun run check         # 一键运行 typecheck + lint + format:check + test

check 是日常开发推荐的质量检查命令。

ESLint 规则

配置文件:eslint.config.js

配置来源 用途
@eslint/js recommended JavaScript 基础规则
typescript-eslint recommended-type-checked TypeScript 类型感知规则no-floating-promises 等)
typescript-eslint stylistic-type-checked TypeScript 风格规则(命名规范、语法选择等)
eslint-plugin-perfectionist recommended-natural 导入语句和命名导出自动排序
eslint-plugin-import 导入路径验证、循环依赖检测、重复导入合并

Prettier 配置

配置文件:.prettierrc.json

显式声明所有格式化参数(printWidth: 120semi: truesingleQuote: falsetrailingComma: "all"endOfLine: "lf" 等),确保不同开发环境产出完全一致的格式化结果。

TypeScript 严格标志

标志 说明
strict true 全局严格模式
noUnusedLocals true 未使用局部变量视为错误
noUnusedParameters false 保留关闭(路由 handler 统一签名需要,如 handleXxx(store, method, mode)
noPropertyAccessFromIndexSignature true 禁止通过点号访问索引签名属性,强制使用括号语法
noUncheckedIndexedAccess true 数组/Map 访问必须运行时真值检查
verbatimModuleSyntax true 强制 import type 纯类型导入

Git Hooks

通过 husky 在 commit 阶段自动执行检查:

Hook 行为
pre-commit lint-staged 对变更文件运行 eslint --fix + prettier --write
commit-msg commitlint 校验提交信息格式 类型: 简短描述

提交类型限定:featfixrefactordocsstyletestchore

bun install 时自动初始化 husky hooks无需手动配置。

测试

bun run check    # 日常开发(类型检查 + lint + 格式 + 单元测试)
bun run verify   # 完整验证check + 构建 + smoke test

已知限制

当前不做告警通知、数据自动清理、拨测目标动态增删、认证鉴权和分布式部署。Command 类型拨测不支持 Windows 环境。