fix(react-runtime): 给 react peer 范围补上上界 ^18.0.0 || ^19.0.0 (#3741) - #3870
Merged
Conversation
…3741) `peerDependencies.react` was `>=18` — the only unbounded react peer in the workspace, against 30 siblings declaring `^18.0.0 || ^19.0.0`. An unbounded range grows on its own: the day React 20 ships, an already-published manifest claims a major nothing here has built against, with no commit to point at. Nothing wanted the wider range. The package's entire React surface is `Component`, `createElement`, `isValidElement`, `ReactElement`, `ReactNode`; `>=18` was written when the package was created (d23d6eb, PR #2105) and no commit since revisited it; and the root `pnpm.overrides` pins React to 19.2.8, so 19 is the only major its tests have ever exercised. The README sentence restating the range moves with the manifest, because doc-version-claims.test.ts compares the two and its header had predicted this exact red ("objectui#3741 ... the day someone does, this test goes red until that README follows"). That prediction, the ledger entry, and the `sameRange` comment whose measured specimen this change removes are rewritten as history plus current state rather than left asserting dead facts. Adds scripts/__tests__/react-peer-range-norm-3741.test.ts, asserting the norm across every workspace manifest. react-runtime is the THIRD package born off-norm (plugin-dashboard d2b6ece, plugin-report #3690/PR #3727) and the first two were corrected in isolation with nothing left to stop a fourth. The existing doc gate could not have caught any of them: it compares a README to its own manifest, and react-runtime's two sides agreed while both said `>=18`.
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
Contributor
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
Collaborator
Author
|
✅ 验收(PM,session 实物核验:头 裁定要点:
转 ready 并挂 auto-merge。 Generated by Claude Code |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #3741
前提复核(先证实,再动手)
基线
origin/main@7fbef94a99ad7c0c2a8d4e737065c8b443619079。git show origin/main:packages/react-runtime/package.json确认"react": ">=18"仍在。前提成立。peerDependencies):声明reactpeer 的 31 个包中 30 个是^18.0.0 || ^19.0.0,唯一例外就是 react-runtime 的>=18;另有 25 个react-dompeer,全部 25 个都是^18.0.0 || ^19.0.0。合计 56 条声明,55 条合规,越界的恰好一条。issue 正文给的数字准确,^18.0.0 || ^19.0.0确是固定组规范。>=18是建包那天(d23d6ebfa,PR feat(page): kind:'html' (full HTML tags) + trusted kind:'react' tier #2105,2026-06-30)写下的,此后该行从未被任何 commit 重新审视过;Component/createElement/isValidElement/ReactElement/ReactNode,React 19 一个都没改,也没碰任何 React 19 移除的 API;pnpm.overrides把 react 钉在19.2.8,19 是这个包的测试唯一跑过的 major —— 无上界的那一端从构造上就没有测试覆盖。因此按缺省方向直接对齐,不留「故意更宽」的注记。
改动
packages/react-runtime/package.json:peerDependencies.react由>=18收窄为^18.0.0 || ^19.0.0。同文件没有其它 peer(该包只声明react一条,无react-dom),全仓也再无第二条无上界 peer。packages/react-runtime/README.md:restate 该范围的那句散文随之改写。scripts/__tests__/doc-version-claims.test.ts:ledger 条目与三处叙述更新(见下)。scripts/__tests__/react-peer-range-norm-3741.test.ts防回归钉子。patch,照 fix(plugin-report): 放宽 react/react-dom peer 到 ^18.0.0 || ^19.0.0,对齐其余 29 个包 (#3690) #3727(同族先例,peer 范围变更)的级别。为什么 README 与 ledger 必须同 PR 改
不是顺手扩面,是被现存门禁强制的联动。
doc-version-claims.test.ts的 peer-line 断言(#3717,#3750 扩面)逐字比对「README 的 peer 行」与「它自己的清单」。react-runtime 的 README 写着react >= 18,只改清单会立刻让该门禁变红。值得一提的是:这份门禁的文件头早就把这次改动写成了预言 —— 原文「objectui#3741, still open, proposes narrowing react-runtime's manifest range; the day someone does, this test goes red until that README follows」。反向验证里它精确地按这句话红了(见下)。该段现已改写为「历史 + 现状」两段(#3749/#3860 的写法)。
同样按「历史 + 现状」改写的还有两处原本会退化成失效断言的叙述:
sameRange的空白归一化,其实测依据正是 react-runtime 的>= 18vs 清单>=18这一对。本次改完,实测 21 条 peer 语句全部与清单逐字节相等,0 条依赖空白归一化 —— 该归一化如今只由自己的单元测试覆盖,不再由语料覆盖。这一点在注释里如实写明(并说清为何仍然保留而不收紧到逐字节:它等同的两种写法都是合法 npm range,收紧买不到任何新的缺陷类)。parsePeerStatement的散文用例改为现行拼法,同时保留>= 18那条(RANGE_OPENS 仍接受>,散文行最可能再被那样写)。README 沿用散文拼法而非改成
**Peer Dependencies:**列表块:它是语料里唯一触发 parser 散文分支的样本,改成列表块会白掉一条真实分支覆盖,且属于无谓改动。防回归钉子:现有门禁看不到这一类
先查:仓内既有 peer 相关门禁两处 ——
workspace-peer-dependency-edges.test.ts(peer 是否能被 turbo^build走到)与上述 peer-line 断言。两者都覆盖不到本 issue 这一类,而且 react-runtime 同时踩中两个盲点:>=18,两边一致,于是这条无上界范围在已发布清单里躺了五周而门禁全绿。一致 ≠ 正确。所以新增钉子问的是另一个问题:清单是否声明了固定组约定的那个范围。形状照抄近邻
workspace-peer-dependency-edges.test.ts(同目录、同主题、同「不设豁免名单」理由):读pnpm-workspace.yaml的 globs(遇到不认识的语法直接 throw 而非跳过)、遍历工作区清单、断言每条react/react-dompeer 逐字等于规范值、带空转下限(包数 > 30、声明数 >= 50,实测 56),并按名钉住 #3741 修的这个包。立钉子的理由是「三次同型」而非一次:react-runtime 是第三个出生即不合规的包,前两个都是各自单独修掉、没留下任何东西阻止第四个 ——
plugin-dashboard生来过窄、2026-05-08 在一个无关构建修复里(d2b6ecec6)顺手改掉;plugin-report生来过窄,直到 #3690 / PR #3727,期间 React 19 用户装它会撞ERESOLVE。规范值写成常量并附理由:下界
^18.0.0是真实支持底线,上界^19.0.0是关键的那一半(阻止清单承诺尚不存在的 major)。将来真支持 React 20,须全仓 56 条一起动否则钉子变红 —— 这正是意图:一个 39 包同发的固定组不该有 per-package 的 React 支持窗口。反向验证(方向先判、后跑)
预判:仅把清单改回
>=18(README 与 ledger 保持已修正状态),应当是常规的「红」向 —— 新钉子红 2 条(通用规范断言 + 按名钉住的 #3741 条),空转下限那条应保持绿;peer-line 断言红 1 条(两侧不再一致)。实跑与预判一致,共 3 红 / 14 绿:
空转下限
discovers the workspace and its React peers如期保持绿 —— 证明红是来自被判定的值,不是来自扫描塌缩。随后恢复,复跑全绿。验证
全部在仓根、
flock /tmp/os-heavy-verify.lock下、NODE_OPTIONS=--max-old-space-size=4096、--maxWorkers=2,未用--转发形式。pnpm --workspace-concurrency=2 --filter '@object-ui/react-runtime^...' build→No projects matched the filters(该包无工作区依赖,唯一 dep 是外部sucrase,如实记录)。pnpm exec vitest run packages/react-runtime/ scripts/__tests__/doc-version-claims.test.ts scripts/__tests__/react-peer-range-norm-3741.test.ts scripts/__tests__/workspace-peer-dependency-edges.test.ts→Test Files 4 passed (4) / Tests 39 passed (39)。pnpm exec turbo run type-check --concurrency=2(CI 同命令)→Tasks: 78 successful, 78 total。pnpm type-check:scripts→ exit 0。turbo run type-check走 package.json 的 scripts,结构上到不了没有 package.json 的scripts/([ci] scripts/ 在零 tsconfig 覆盖内:turbo type-check 从不检查 scripts/__tests__/*.ts——一批门禁 pin 测试自身无类型门 #3494 的原委),新钉子若只靠 turbo 会是编译器从未读过的钉子;另经tsc --listFiles确认该文件确实在被编译,并跑scripts-type-check.test.ts→ 8 passed。pnpm exec eslint两个 scripts 文件 → exit 0。no-major/fixed/presence)。node scripts/check-control-bytes.mjs→ OK(3763 文件);改动文件grep -naP '[\x00-\x08\x0b\x0c\x0e-\x1f]'零命中。pnpm install后git status --porcelain无pnpm-lock.yaml—— peer 范围收窄未触发 lockfile 变化(root overrides 已把 react 钉在 19.2.8,解析结果不变)。协调
文件面与在飞 #3849 / #3546 切片六 / #3735 / #3746 零相交。#3735 同在
scripts/,但本 PR 只新增一个独立文件(名带 3741)并改doc-version-claims.test.ts,与其面不重叠。Generated by Claude Code