开源项目archify的源码分析一:系统架构分析

1 阅读4分钟

系统架构

目录总览

仓库主体是一个可独立分发的 Skill 包,位于 archify/;仓库根目录承载文档站、示例产物、基准测试与社区集成。

archify/
├── bin/                     # CLI 入口与命令实现
│   ├── archify.mjs          # 主分发器(render/validate/deliver/finalize/...)
│   ├── finalize.mjs         # 四级门禁编排
│   ├── preview.mjs          # loopback 实时预览会话
│   ├── visual-check.mjs     # 无头浏览器截图与复核
│   ├── recover-output.mjs   # 原子发布崩溃后的恢复工具
│   └── open-artifact.mjs    # 跨平台打开产物
├── renderers/
│   ├── architecture/        # 架构图:grid 布局、正交布线、自动标签
│   ├── workflow/            # 工作流:泳道、workflow-compiler、v2 迁移几何
│   ├── sequence/            # 时序图:参与者列、生命线、消息
│   ├── dataflow/            # 数据流:来源、转换、存储与边界
│   ├── lifecycle/           # 生命周期:泳道网格、状态标记、轨道布线
│   └── shared/              # 跨渲染器共享层(见下)
├── schemas/                 # 五份 JSON Schema 2020-12 + common
├── assets/
│   ├── template.html        # Viewer 模板(约 728KB,内联字体与运行时)
│   └── JetBrainsMono-OFL.txt
├── examples/                # 每种类型的示例 IR 与多语言消息目录
├── references/              # 面向 Agent 的创作契约文档
├── migrations/              # schema 迁移(workflow v1→v2)
├── scripts/                 # 验证器生成、品牌标记生成、示例批量渲染
└── test/                    # 170 个测试文件,含真实浏览器测试

共享层 renderers/shared/ 是架构的关键,它把五类图表的共性收敛成一组稳定模块:

模块职责
cli.mjs渲染管线公共头:读入 IR、安装诊断边界、套模板、写产物
atomic-output.mjs描述符绑定与原子发布协议(见原子输出机制)
validator.mjs / generated-validators.mjsAJV Schema 校验,后者构建期生成
geometry.mjs矩形相交、线段净空、折线布线、箭头碰撞等几何原语
spatial-grid.mjs统一空间索引,支撑标签避让与碰撞检测
route-quality.mjs绕路、走廊歧义、共享主干等布线质量判定
text-fit.mjs字号拟合与文本可用宽度估算(含 CJK、VS15/16 处理)
legend.mjs图例占位测量与避让
diagnostics.mjs结构化诊断的记录、归一化与进程边界
repository-evidence.mjsGit 固定提交的源码证据校验
output-path.mjs / sidecar-path.mjs / portable-path.mjs / path-semantics.mjs输出路径规范化与跨平台路径语义
i18n.mjsViewer UI 语言解析与消息键回退
brand-marks.mjs / generated-brand-marks.mjs品牌标记:内置矢量与站点图标捕获、摘要钉版

分层与依赖方向

Agent / 用户 prompt
        │ 编写
        ▼
Typed JSON IR  ──────────► JSON Schema(封闭字段)
        │                         │
        ▼                         ▼
  bin/archify.mjs 分发     generated-validators(AJV 代码生成)
        │
        ▼
renderers/<type>/   ── 类型专属:布局语义、布线策略、SVG 结构
        │
        ▼
renderers/shared/   ── 几何、诊断、证据、i18n、品牌
        │
        ▼
assets/template.html 占位替换 ── 自包含 HTML 产物
        │
        ▼
atomic-output 发布到目标路径

依赖方向严格自上而下:类型渲染器依赖共享层,共享层不反向依赖任何具体类型。每个渲染器文件同时支持两种入口——由主 CLI 以子进程方式拉起,或被测试与编译器直接 import。

一次渲染的数据流

以 render architecture web-app.architecture.json out.html 为例:

  1. 主 CLI 校验命令行参数,解析 --quality、--repo-root,spawn 对应的 render-architecture.mjs。
  2. 渲染器入口调用 loadDiagramWithBrandMarks:读取字节、解析 JSON、安装进程级诊断边界、准备品牌标记。
  3. AJV 独立验证器校验 Schema;若声明了 meta.repository 或节点 sources,运行 Git 证据校验。
  4. 工程画像(如 deployment-ownership)在 Schema 之外做事实级阻断校验。
  5. 类型渲染器执行布局:架构图走 gridLayout 网格定位与边界矩形推导,工作流走编译器与泳道规划,生命周期走共享 0–4 列网格。
  6. 布线器产出正交折线:自动端点展开、扇出端口分配、走廊歧义消解、交叉与贴边检测。
  7. 标签放置:测量文本、预留避让矩形、检查与其他路线和画布边界的净空。
  8. 合成内联 SVG(语义符号、定义、箭头、图例、无障碍文本),套入 template.html 的占位符。
  9. 几何与 HTML/SVG 门禁全部通过后,原子输出模块在目标同目录生成候选并发布(render 直接写,deliver/finalize 走完整发布协议)。

任何一步失败都不会抵达第 9 步:错误经诊断边界归一化为 {code, severity, subject, evidence, supportedFixes},进程以非零退出,目标路径上的旧产物保持不变。

进程模型

CLI 的一个刻意设计是"每个渲染器一个子进程"。主 archify.mjs 只做参数解析与分发,通过 spawnSync 运行类型渲染器。这样做有三个后果:

  • 单个渲染器崩溃不会污染主进程,错误可以被统一捕获并归类为可读诊断而非 Node 堆栈。
  • 渲染器可以直接 node render-x.mjs input.json output.html 独立运行,测试不需要经过 CLI。
  • --layout-json 等调试开关通过进程参数透传,渲染器之间不共享可变全局状态。

preview 会话则是长进程:一个 127.0.0.1 HTTP 服务加一个受监听的 JSON 文件,防抖 400ms 后拉起交付子进程,只有校验通过的候选才刷新浏览器看到的版本。