越界发现,记录于 #3742 (把生成产物的 build 侧 devDependencies 锚到仓内工具链,PR #3754 )期间。#3742 的范围明确是 devDependencies (test + build 八条),这一条位于生成产物的 dependencies ,因此没有在那个 PR 里修 —— PR #3754 新加的完整性闸门也只覆盖 devDependencies,扫不到它。
事实(对 origin/main @ b1a67e0f6 实测)
packages/create-plugin/src/templates.ts 的 buildPackageJson 给生成的插件写入:
dependencies: {
'@object-ui/components': 'workspace:*',
'@object-ui/core': 'workspace:*',
'@object-ui/react': 'workspace:*',
'@object-ui/types': 'workspace:*',
'lucide-react': '^0.563.0'
}
两个问题:
1. 区间落后两个 major,而且不会自己浮上去。
$ git grep -h '"lucide-react":' -- '*/package.json' | sed 's/^ *//' | sort | uniq -c
15 "lucide-react": "^1.28.0",
8 "lucide-react": "^1.28.0"
仓内 23 处声明全部是 ^1.28.0 (packages/components、packages/plugin-grid、packages/plugin-charts 等),只有模板写 ^0.563.0。npm 上当前 latest 是 1.30.0。
比普通的 caret 漂移更糟的一点:0.x 的 caret 不跨 minor 浮动 —— ^0.563.0 等价于 >=0.563.0 <0.564.0,只锁在 0.563.x 这一个 minor 上,连 0.x 内的后续版本都拿不到。所以脚手架不是「落后但会慢慢追上」,是被钉死的。
$ npm view lucide-react version
1.30.0
$ npm view lucide-react@^0.563.0 version
0.563.0
2. 生成的源文件里没有任何一处 import 它。
lucide-react 在 templates.ts 里只出现一次,就是上面那行声明:
$ grep -rn "lucide-react" packages/create-plugin/src/templates.ts
125: 'lucide-react': '^0.563.0'
buildIndexFile / buildImplFile / buildTypesFile / buildTestFile 都不 import 它。也就是说这是一条声明了但没被用到 的运行时依赖 —— PR #3733 加的 "import nothing the generated package.json does not declare" 是单向的(禁止未声明的 import),不检查反向的未使用声明,所以它一直没被发现。
影响(如实说:今天没有东西是红的)
新脚手架插件 pnpm install 会真实装下 lucide-react 0.563.x。在 pnpm workspace 里这就多出一个与仓内 1.28 并存的 major。
生成产物的 build / test 两者都不受影响(没人 import 它),所以这不是一条会让人立刻看到失败的缺陷。
会真正咬人的场景:作者在插件里写 import { Flame } from 'lucide-react'(对一个插件来说是很自然的动作),拿到的是比所有仓内兄弟包旧两个 major 的图标库 API。
严重度我不预设 —— 「安装确实装下了旧 major」偏具体缺陷,「今天没有失败」偏 observation。留给 triage 定级,故未打 finding 标签,也未排队。
可选方向(不预设结论)
锚到 ^1.28.0 并保留声明 —— 与仓内 23 处一致;如果认为脚手架应当预置图标库,这是最省事的一致化。若走这条,顺手把它纳入 PR fix(create-plugin): 把脚手架 build 侧 devDependencies 锚到仓内工具链,并把整张清单钉进 parity 测试 #3754 的锚点表(把该表从 devDependencies 扩到 dependencies),否则它会以同样的方式再漂一次。
直接删掉这条声明 —— 既然没有任何生成源文件 import 它,按「声明即使用」这条更干净;作者要用图标自己 pnpm add 即可,而且那时装到的自然是当前版本。生成的 dependencies 就只剩四条 workspace:*。
保留并在模板里真的用上一个图标 —— 只有在确实想让脚手架示范图标用法时才值得,成本是给示例组件增加一个无关的关注点。
倾向方向 2 或 1:两者都能消除漂移,区别在于「脚手架是否应该预置图标库」这个产品判断,该由维护者定。方向 1 若不同时扩锚点表,等于把同一个坑留在原地。
Generated by Claude Code
越界发现,记录于 #3742(把生成产物的 build 侧 devDependencies 锚到仓内工具链,PR #3754)期间。#3742 的范围明确是 devDependencies(test + build 八条),这一条位于生成产物的
dependencies,因此没有在那个 PR 里修 —— PR #3754 新加的完整性闸门也只覆盖 devDependencies,扫不到它。事实(对
origin/main@b1a67e0f6实测)packages/create-plugin/src/templates.ts的buildPackageJson给生成的插件写入:两个问题:
1. 区间落后两个 major,而且不会自己浮上去。
仓内 23 处声明全部是
^1.28.0(packages/components、packages/plugin-grid、packages/plugin-charts等),只有模板写^0.563.0。npm 上当前 latest 是1.30.0。比普通的 caret 漂移更糟的一点:
0.x的 caret 不跨 minor 浮动 ——^0.563.0等价于>=0.563.0 <0.564.0,只锁在 0.563.x 这一个 minor 上,连 0.x 内的后续版本都拿不到。所以脚手架不是「落后但会慢慢追上」,是被钉死的。2. 生成的源文件里没有任何一处 import 它。
lucide-react在templates.ts里只出现一次,就是上面那行声明:buildIndexFile/buildImplFile/buildTypesFile/buildTestFile都不 import 它。也就是说这是一条声明了但没被用到的运行时依赖 —— PR #3733 加的 "import nothing the generated package.json does not declare" 是单向的(禁止未声明的 import),不检查反向的未使用声明,所以它一直没被发现。影响(如实说:今天没有东西是红的)
pnpm install会真实装下 lucide-react 0.563.x。在 pnpm workspace 里这就多出一个与仓内 1.28 并存的 major。import { Flame } from 'lucide-react'(对一个插件来说是很自然的动作),拿到的是比所有仓内兄弟包旧两个 major 的图标库 API。严重度我不预设 —— 「安装确实装下了旧 major」偏具体缺陷,「今天没有失败」偏 observation。留给 triage 定级,故未打
finding标签,也未排队。可选方向(不预设结论)
^1.28.0并保留声明 —— 与仓内 23 处一致;如果认为脚手架应当预置图标库,这是最省事的一致化。若走这条,顺手把它纳入 PR fix(create-plugin): 把脚手架 build 侧 devDependencies 锚到仓内工具链,并把整张清单钉进 parity 测试 #3754 的锚点表(把该表从 devDependencies 扩到dependencies),否则它会以同样的方式再漂一次。pnpm add即可,而且那时装到的自然是当前版本。生成的dependencies就只剩四条workspace:*。倾向方向 2 或 1:两者都能消除漂移,区别在于「脚手架是否应该预置图标库」这个产品判断,该由维护者定。方向 1 若不同时扩锚点表,等于把同一个坑留在原地。
Generated by Claude Code