Skip to content

docs(guide): plugin skeleton 声明 @vitejs/plugin-react,并把该行入版本声称锚 (#4961) - #4985

Merged
yinlianghui merged 1 commit into
mainfrom
claude/issue-4961-skeleton-plugin-react-dep
Aug 17, 2026
Merged

docs(guide): plugin skeleton 声明 @vitejs/plugin-react,并把该行入版本声称锚 (#4961)#4985
yinlianghui merged 1 commit into
mainfrom
claude/issue-4961-skeleton-plugin-react-dep

Conversation

@yinlianghui

Copy link
Copy Markdown
Collaborator

Fixes #4961

同文件串行门:PR #4963 在派发前已落 main(merged 11:58:37Z,分诊认领评论 11:58:50Z),无需等待循环。本分支从其落地 sha 7d1017790 切出,用的正是它落地的 skeletonDep 机制。

前提验证:成立,卡上三个测量值全部复核无漂移

三样都对着 7d1017790 重新读过,没有沿用卡上的数字:

卡上写的 本次实测
step 5 的 import :340 import react from '@vitejs/plugin-react',并在 plugins: [react()] 用掉 ✅ 一字不差,行号仍是 340
step 6 的 devDependencies :397-403,五条,无 @vitejs/plugin-react ✅ 成立;全页仅 :340 一次 import 提到该包
仓内锚 @vitejs/plugin-react ^6.0.5,19/19 ^6.0.5,19/19 全一致(逐个 packages/plugin-*/package.json 读过)

卡上写的「锚现成且一致,不需要任何判断」成立。与 #4963 的经历不同,这次九天里锚没有漂 —— 但仍是重测过才敢用。

改法(两个文件 + 一条 changeset)

  1. content/docs/guide/plugins.md:401 的 devDependencies 增 "@vitejs/plugin-react": "^6.0.5",按仓内 plugin 清单的字典序位置(@object-ui/types 之后、typescript 之前)。
  2. scripts/__tests__/doc-version-claims.test.ts:第三条 kind: 'anchored' + skeletonDep: '@vitejs/plugin-react'KNOWN_CLAIMS 条目;两条真空下限 2 提到 3;resolves the anchor unanimously 的派生下限名单加一个名字。没有新机制 —— docs(guide): plugin skeleton 的 vite/typescript 对齐仓内实测,并把该拼写纳入版本声称门 (#3855) #4963 第 3 个 commit 留的派生下限正是为这种后续新增设计的,这一单是它的第一个用户。
  3. 头部注释加一节 ## What objectui#4961 added

一处非显然的事实,值得点名而不是让下个读者踩

该行被扫出来的 claim key 是 react": "^6.0.5,不是 @vitejs/plugin-react": "^6.0.5"。原因:ReactTOOLCHAIN 词,而 @vitejs/plugin-reactreact 前面的 - 构成词边界,于是匹配从 react 起,记下的字面量是包名的尾巴,指向一个与该行实际声明不同的包。

这恰好是 skeletonDep 那段注释所说「dep 名写出来而不是从 claim 文本派生」的第一个真实用例 —— parseManifestLine整行,所以比对仍然打在 @vitejs/plugin-react 上(见下方变异 ②b/③ 的红法,报的是 @vitejs/plugin-react 而非 react,这就是机械证据)。条目上加了行内注释说明。

逆向验证:四个变异,方向都先预测后跑;两个的方向与任务卡的预设不一致,据实回报

任务卡给的两条是「①删掉新增行 → 骨架断言红;②版本改假值 → 锚红」。①如预期;②按字面做到不了锚的比对支路,原因是结构性的,与 #4963 变异 A 同一条:清单键内嵌版本字面量。下面把两半分开跑。

变异 ① —— 临时删掉新增的 doc 行

预测:红 2 条,且骨架断言的红来自「真空下限」而非比对支路 —— 字面量离开树 → 条目变孤儿(上行棘轮红);skeletonChecks 该项 absent: true → 比对循环故意跳过,但 stated 为空 → 比对行数和从 3 掉到 2,撞下限。

× keeps the inventory honest - no entry may outlive the claim it excuses
  AssertionError: KNOWN_CLAIMS names version claims that are no longer in the tree
× pins the skeleton toolchain to the range the in-repo plugin packages declare
  AssertionError: the skeleton assertion compared implausibly few lines ...
  expected 2 to be greater than or equal to 3
  Tests  2 failed | 16 passed (18)

逐条对上。「骨架断言红」成立,但红的是下限而不是比对 —— 据实写明,不套模板。

变异 ②a —— 只把 doc 里的值改成 ^9.9.9(任务卡的字面读法)

预测:红 3 条,锚的比对支路仍然跳过。 键含版本字面量,所以改值同时造出一条未记账的新 claim(下行棘轮)并让旧条目变孤儿(上行棘轮),该项再次 absent

× records every version literal on the scanned surfaces
  - content/docs/guide/plugins.md:401  "react": "^9.9.9"
× keeps the inventory honest ...
  - content/docs/guide/plugins.md :: react": "^6.0.5
× pins the skeleton toolchain ...   expected 2 to be greater than or equal to 3
  Tests  3 failed | 15 passed (18)

所以「版本改假值 → 锚红」按字面做不成立:值被两个方向的棘轮先钉住了,比对支路根本没轮到。要真的动到锚,得让记下的字面量与 doc 行一致、而与仓内不一致 —— 即下面两个变异。

变异 ②b —— doc 值与清单键同步改成 ^9.9.9(真实的误操作形状:页面和账本一起 bump 了,仓内没有)

预测:恰好一条红,走比对支路,点名行号与两侧区间。

× pins the skeleton toolchain ...
  - content/docs/guide/plugins.md:401  @vitejs/plugin-react: the page teaches "^9.9.9",
    every in-repo plugin package declares "^6.0.5"
  Tests  1 failed | 17 passed (18)

注意报的是 @vitejs/plugin-react,不是 claim key 里那个 react —— 上文那段的机械证据。

变异 ③ —— bump 全部 19 个 plugin 清单到 ^7.1.0,文档留在原地

这才是这条门存在的那个场景(下次仓升级同一行再化石化)。预测:恰好一条红走比对支路,且 resolves the anchor unanimously 保持绿 —— bump 做完了就是一致的,只有文档旧,两条断言判两件不同的事。

× pins the skeleton toolchain ...
  - content/docs/guide/plugins.md:401  @vitejs/plugin-react: the page teaches "^6.0.5",
    every in-repo plugin package declares "^7.1.0"
  Tests  1 failed | 17 passed (18)

变异 ④ —— 抽掉新条目的 skeletonDep(证我扩的那条派生下限真的咬)

预测:红 2 条 —— 计数下限 + 派生名单点名新 dep。

× pins the skeleton toolchain ...
  AssertionError: no inventory entry carries skeletonDep - the three plugin-guide entries
  lost the field ...: expected 2 to be greater than or equal to 3
× resolves the anchor unanimously ...
  AssertionError: @vitejs/plugin-react lost its skeletonDep entry - either the plugin guide
  stopped naming it or the inventory did ...
  expected [ 'typescript', 'vite' ] to include '@vitejs/plugin-react'
  Tests  2 failed | 16 passed (18)

四个变异全部还原后复跑 18 passed,git status 只剩本 PR 的三个文件。

测试

$ pnpm exec vitest run scripts/__tests__/doc-version-claims.test.ts
   Test Files  1 passed (1) ;  Tests  18 passed (18)      # 基线 18(#4963 后),条数不变
$ pnpm exec vitest run scripts/ --maxWorkers=2
   Test Files  50 passed (50) ;  Tests  1171 passed (1171)
$ pnpm run type-check:scripts                    exit=0
$ pnpm exec turbo run type-check --concurrency=2  Tasks: 81 successful, 81 total
$ pnpm exec eslint scripts/__tests__/doc-version-claims.test.ts   exit=0
$ node scripts/check-control-bytes.mjs   ✅ OK (scanned 4439 tracked text file(s); skipped 85 binary)
$ grep -naP '[\x00-\x08\x0b\x0c\x0e-\x1f]' 本 PR 三个文件      0 命中
$ pnpm run changeset:check   ✅ fixed group OK;✅ 无 major
$ node scripts/check-doc-links.mjs   Links are valid across 13 scan roots.

新增字面量本身不新增测试条数 —— 它是被现成断言接住的,这正是 #4963 那半个交付物的目的;新增的覆盖体现在两条下限从 2 升到 3(变异 ①/④ 是它咬人的证据)。

消费半径扫过

按规则的调用者而非改动的包来扫:读 guide/plugins.md 的除本门禁外只有 check-doc-links.mjs 及其测试,后者用自建内存 fixture('guide/plugins.md': '[Charts](...)'),不碰版本字面量。全仓 grep plugin-myfeature 只命中本 PR 这两个文件。另外 grep 了全仓 @vitejs/plugin-react 的其它拼写面(packages/clipackages/create-plugin 的生成器测试、content/docs/utilities/cli.mdx),均未受本改动影响。

顺带核过、明确没动的两处(卡面预核,复核后同意)

  • 骨架的 peerDependencies react/react-dom ^18.0.0 || ^19.0.0:peer 说「拷走后向宿主接受什么」,由该插件作者拥有,与「在这里装什么来构建」是两件事。该条目照旧 sample
  • 骨架没有 vite-plugin-dts,而 19 个 plugin 包都有 —— 不是缺项:骨架 build 脚本是 vite build && tsc --emitDeclarationOnly,声明文件由 tsc 自己出。两种写法都自洽。

这一点在头部注释里写成了显式边界,因为这条断言正好邀请一个错误推论:它判的是页面已经命名的依赖的区间,是「骨架该声明仓内清单声明的一切」。让 plugin-react 该在的理由不是它出现在清单里,而是 step 5 用了它 —— 页面自我矛盾,清单只在该行必须存在之后提供了区间。

另外两条纪律

  • ⛔ 未触碰 content/docs/releases/**
  • ⛔ 未 force-push;单分支单 commit。

越界发现(只记录、不顺手修)

另外核过但判定不是缺陷、故未立卡:content/docs/guide/quick-start.md:45building-crud-app.md:41 同样 import react from '@vitejs/plugin-react' 却没有对应的 install 指令 —— 但这两页的第一步是 pnpm create vite my-app --template react-ts,该模板自带 @vitejs/plugin-react,所以 import 有着落,不是 #4961 那个形状。写在这里是因为「同一 import 出现在三页」很容易被机械判成三处同样的缺陷。


🤖 Generated with Claude Code

https://claude.ai/code/session_01GTRjn8xBqp75dk7kFupVRt


Generated by Claude Code

Step 5 of the numbered plugin tutorial writes vite.config.ts with
`import react from '@vitejs/plugin-react'` and calls react() in plugins;
step 6's devDependencies never declared it, and that import was the only
mention of the package on the page. A reader following 1-6 hit their first
`pnpm build` with a config importing something they were never told to
install. Declares it at ^6.0.5 - the range all 19 in-repo plugin manifests
declare unanimously.

The literal is anchored rather than recorded: a third `anchored` KNOWN_CLAIMS
entry carrying skeletonDep, which #3855's derived floor absorbs without a new
mechanism. Deliberately untouched on the same block: the peerDependencies
react range (owned by the copied plugin's author) and the absence of
vite-plugin-dts (declarations come from tsc --emitDeclarationOnly).

Co-authored-by: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added the tests label Aug 17, 2026

Copy link
Copy Markdown
Collaborator Author

PM 验收 ✅ ACCEPT(#4961,批次 20)

实物核验(按真实 merge-base 对账):3 files,+86/−10 —— content/docs/guide/plugins.md step 6 加一行 "@vitejs/plugin-react": "^6.0.5";scripts/__tests__/doc-version-claims.test.ts 第三条 kind:'anchored' 条目 + 两处 vacuity floor 2→3 + unanimity 派生名单扩展;changeset。premise 对 post-#4963 的 main 复验成立(page 唯一提及在 step 5 的 import,step 6 从未声明 —— 页面自相矛盾),锚前再测 19/19 个 packages/plugin-*/package.json^6.0.5 未漂。模型标识 grep = 0;releases/ 零触碰。

CI 亲读:19/19 check runs completed,零失败(dependabot/coverage 两项 path-filter skipped 计绿;shard 2 12:37:53Z 收尾)。

偏差判定:卡面点名的 DEPENDENCY_ANCHORS#4963 落地形态中不存在,dev 按真实机制(KNOWN_CLAIMS + skeletonDep + 派生 floor)扩条目 —— 正是「按其新形态扩一条」的正确读法,不算偏离。

反向验证读数(四变异,两处方向与卡面预设相反、均如实报告):(2a) 只改 doc 的假版本够不到比对支路 —— inventory key 内嵌版本字面量,先被孤儿化棘轮抓住,与 #4963 变异 A 同构;(2b) doc+key 同步改 → 恰 1 红且报错点名 @vitejs/plugin-react(锚经 parseManifestLine 全行解析的机械证明 —— claim key 实为 react": "^6.0.5,React 是 toolchain 词、连字符成词边界,这是 skeletonDep 必须写名而非从 key 派生的第一个实测例证,已文档化);(3) 19 manifests 全 bump、doc 停滞 → 恰 1 红(门存在的那个漂移方向);(4) 剥 skeletonDep → floor + 成员断言 2 红。方向反转如实报告不套模板,验收按此记为诚实产出。

边界核验:peer range 保持 kind:'sample'(宿主接受面归页面作者)与 vite-plugin-dts 缺席(骨架 build 走 tsc --emitDeclarationOnly)两处「不用动」都重验过并写进 header;quick-start/building-crud-app 的同名 import 判非缺陷(create vite 模板自带),防了三连误判。finding #4981(doc-version-claims SCAN_ROOTS 不含 skills/,4 个版本化石最多落后 2 个 major)已入池待分诊。

undraft + auto-merge(squash)。


Generated by Claude Code

@yinlianghui
yinlianghui marked this pull request as ready for review August 17, 2026 12:40
@yinlianghui
yinlianghui added this pull request to the merge queue Aug 17, 2026
Merged via the queue into main with commit 1f4504b Aug 17, 2026
20 checks passed
@yinlianghui
yinlianghui deleted the claude/issue-4961-skeleton-plugin-react-dep branch August 17, 2026 12:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

2 participants