Files
cms-website/docs/adr/ADR-016-阶段2依赖与接线决策.md
T
浅念 2a0d830520 docs: 阶段2收尾——ADR-016/typecheck链/阶段3移交清单/README
- ADR-016:saxes ^6.0.0(勘误:计划曾误写 ^0.9)/commander ^14 根依赖/清洗三件套
  同 range + 镜像直调 launder.naughtyHref/tsx ^4 CLI 直吃 TS;跨包接线(根 tsconfig
  paths 三方消费、build 侧 dist+prebuild、tsconfig 双链型并存);根 engines 升
  >=22.12(对齐 sanitize-html 2.18 engines,CI node 22 与本机 24 均满足)
- 根 typecheck 链扩为四段:追加 pnpm --filter @sf/adapter-wp typecheck
- Plan 2 文末新增"移交阶段 3 清单"定稿(7 项:taxonomyRefs 自建缺失 term、
  media_bundle 映射、connection 库级唯一索引、REST 重审项、导入消费接口、
  Task 0.2 cms 备份续传携带、versions.ts bump 纪律);Task 9 与验收节勾选
- README:快速开始加 pnpm sf 示例;目录结构/文档导航/当前状态更新为阶段 2 完成
- 三绿:lint / typecheck(四段)/ test 263 全部通过(数量不变)

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-21 13:34:15 +08:00

24 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.
# ADR-016:阶段 2 新增依赖与跨包接线
- **状态**:已采纳(Plan 2 Task 9 收尾,阶段 2;许可证已逐项核验——saxes ISC,commander/sanitize-html/parse-srcset/launder/tsx 均 MIT)
## 决策一:新增依赖(选型 / 版本范围 / 定位)
1. **saxes `^6.0.0`**(@sf/adapter-wp 运行时依赖)——WXR 流式 SAX 解析的唯一解析库。**勘误**:Plan 2 Task 3 曾误写"锁 ^0.9"(0.x 是多年前的旧版本线),实施时按 npm 实际主线锁 `^6.0.0`;默认不解析外部实体(XXE 面由测试钉死)。`versions.ts` 的 `PARSER_VERSION` 常量须与实际解析版本同步(当前 `'saxes 6.0.0'`)。
2. **commander `^14.0.0`(根依赖)**——CLI 入口在仓库根 `scripts/sf.ts`,而 @sf/adapter-wp 定位纯函数包、不消费 CLI 框架;commander 放根,不给库包带入无关运行时依赖。
3. **清洗三件套 `sanitize-html ^2` + `parse-srcset ^1` + `launder ^1`**(@sf/adapter-wp 运行时依赖,三条 range 并存)——sanitize-html 是清洗本体;srcset/imagesrcset 审计用 parse-srcset(sanitize-html 内部即同库依赖);URL 拒绝判定**直接调用 `launder.naughtyHref`**——sanitize-html 2.18 内部即解构调用同一函数,镜像判定与库本体零漂移(依赖升级时由参数化对抗测试护栏兜底)。三件套用同一主版本 range 跟随解析:launder/parse-srcset 本是 sanitize-html 的传递依赖,若单独锁死版本,会造成"镜像调用的 launder"与"库内部用的 launder"版本 skew。类型:@types/sanitize-html、@types/parse-srcset 走 devDependencies;launder 无官方类型,本包自带 d.ts 垫片(`src/types/launder.d.ts`)。
4. **tsx `^4`(根 devDependency)**——CLI 直吃 TS 源码:`pnpm sf` = `tsx scripts/sf.ts`,无需预构建 dist(apps/api 的 Nest 装饰器源码同样可跑);tsx 属开发工具链,不进任何运行时依赖。
## 决策二:跨包接线
5. **根 tsconfig paths 三方消费(单源)**:`@sf/contracts` 与 `@sf/adapter-wp` 到各自 `src/index.ts` 的映射只在根 `tsconfig.json` compilerOptions.paths 维护一份——包级 tsc 经 extends 继承;vitest 不读 tsconfig paths,由 `vitest.config.ts` 的 `resolve.alias` 镜射同一映射;tsx 原生读 tsconfig paths。三方(包级 tsc / vitest / tsx)全部直连 `src/index.ts`——日常开发链 import 不经 dist、无预构建依赖。
6. **build 侧 dist + prebuild**:@sf/adapter-wp 的 `tsconfig.build.json` 把 `@sf/contracts` 改指 `packages/contracts/dist/src/index.d.ts`(emit 程序不得包含包外源文件,TS6059),由 prebuild 先 `pnpm --filter @sf/contracts build` 供给 dist 声明。dist 只为发布产物完整性负责;typecheck / test / CLI 通道不依赖它。
7. **tsconfig 双链型并存**:contracts extends `tsconfig.base.json`(无跨包 import,不需要 paths);adapter-wp extends **根 tsconfig.json**(为继承 baseUrl/paths 跨包映射)。两条 extends 链并存是有意的:包是否需要跨包映射决定挂哪条链,不为形式统一强行并链。**src-vs-dist 的最终口径即上述 5+6:开发链 src 直连、build 链 dist+prebuild,双轨并存**(Plan 1 终审前瞻项在此落定)。
## 决策三:engines 口径
8. **根 engines 升 `>=22.12`**:sanitize-html 2.18 的 engines 要求 node `>=22.12.0`,根原口径 `>=22` 会放行 sanitize-html 不支持的 22.0–22.11。升根一行对齐(CI 的 node 22 取最新 22.x、本机 24 均满足);否决的替代方案是 pin sanitize-html 旧版——为迁就旧 patch 版 node 反向锁死清洗库,不取。后续新增依赖若 engines 高于根,同理评估升根而非降依赖。
- **理由**:全部依赖均为单一职责引入(解析/清洗/CLI/TS 执行各一),无重叠;版本范围统一锁主版本(`^`),与"锁版本 + 核许可证 + 记 ADR"的新增依赖三纪律一致;跨包接线坚持单源配置(paths 一份、alias 镜射),把 skew 面压到最小。
- **权衡/陷阱**:① vitest alias 是根 paths 的人工镜射,新增 workspace 包时两处要同步改;② build 链与开发链对 `@sf/contracts` 的解析目标不同(dist 声明 vs src),dist 过期只影响产物不影响日常——发布前跑 build 即可暴露;③ launder 镜像判定的等价性依赖"sanitize-html 内部继续用 launder 同一函数",升级 sanitize-html 大版本时须重验(对抗测试在 `test/html-sanitize.test.ts`);④ engines 对齐的是传递依赖里最严的要求,属"就高"策略,接受它对低版本 node 的排斥。