越界发现,记录于 #3715 (create-plugin.mdx 按 route B 收缩)期间。那一单的文件面是 content/docs/** + ledger,packages/create-plugin/** 明确越界(且 #3742 在途改同一个文件),因此这里只记录,不在那个 PR 里修。
事实(对 origin/main @ 0c28a0720 实测)
packages/create-plugin/src/templates.ts 的 buildPluginFiles()(:364)把 buildTypesFile()(:303)的产物写成 src/types.ts,内容是一个 Schema 接口(type 键 = 注册键,外加 id? / className?)。
它在包内外都到不了:
没有任何生成源文件 import 它。 grep "from './types" packages/create-plugin/src/templates.ts 为空。buildIndexFile 的导出面只有两行(:250-251):export { PascalName },以及 export type { PascalNameProps } from './PascalNameImpl' —— Props 接口来自 Impl 文件,与 src/types.ts 里那个 Schema 接口无关。
生成的 package.json 的 exports 只有 . (:88-94 → dist/index.js / dist/index.umd.cjs / dist/index.d.ts)。既然 entry 不再导出它,深路径(包名/types、包名/dist/types)又被 exports map 关掉,消费者没有任何合法途径 import 到那个接口。
顺带说明门禁现状:src/__tests__/templates.test.ts:177 只断言 src/types.ts 在文件映射里存在 ,不断言它可达;#3733 加的 "import nothing the generated package.json does not declare" 是单向 的(禁未声明的 import,不查未被使用的产物),这与 #3755 指出的同一个盲区。
影响(如实说:今天没有东西是红的)
生成产物的 build 和 test 都不碰它,所以没有任何命令会因此失败 —— 属 observation 级,故打 finding、不排队。真正的成本在契约面:schema 接口正是元数据作者与渲染器之间的契约,脚手架生成了一份却让它不可达,作者要么以为已经导出、要么在自己的代码里重写一遍。
有一点值得记下来:被 #3715 删掉的那页旧文档虚构的 entry 形状里写的是 export * from './types' —— 那句虚构恰好比真实模板更合理,这也是为什么它当年读起来没人起疑。
可选方向(不预设结论)
entry 补一行 export * from './types'; —— 让脚手架自带的契约真的可达,改动最小。
删掉 src/types.ts —— 既然无人 import,按「声明即使用」更干净,Props 接口(已在 Impl 导出)成为唯一契约面;与 create-plugin 生成产物的 dependencies 里 lucide-react: '^0.563.0' 被钉死在 0.563.x(仓内 23 处均为 ^1.28.0),且没有任何生成的源文件 import 它 #3755 的方向 2 同一取向。
保留并在 exports 里加一条 ./types 子路径 —— 成本最高、收益最小。
倾向 1 或 2,分歧点是「脚手架是否应当预置一个 schema 类型面」这个产品判断,该由维护者定。
同族与串行
与 #3742 (PR #3754 ,生成产物 devDependencies 锚定)和 #3755 (生成产物 dependencies 的 lucide-react)同族、同文件(templates.ts),但三者范围互不覆盖:那两条是清单条目,这一条是源文件与 exports 面。落地时需与它们串行,避免同文件三方冲突。
Generated by Claude Code
越界发现,记录于 #3715(
create-plugin.mdx按 route B 收缩)期间。那一单的文件面是content/docs/**+ ledger,packages/create-plugin/**明确越界(且 #3742 在途改同一个文件),因此这里只记录,不在那个 PR 里修。事实(对
origin/main@0c28a0720实测)packages/create-plugin/src/templates.ts的buildPluginFiles()(:364)把buildTypesFile()(:303)的产物写成src/types.ts,内容是一个 Schema 接口(type键 = 注册键,外加id?/className?)。它在包内外都到不了:
grep "from './types" packages/create-plugin/src/templates.ts为空。buildIndexFile的导出面只有两行(:250-251):export { PascalName },以及export type { PascalNameProps } from './PascalNameImpl'—— Props 接口来自 Impl 文件,与src/types.ts里那个 Schema 接口无关。package.json的exports只有.(:88-94→dist/index.js/dist/index.umd.cjs/dist/index.d.ts)。既然 entry 不再导出它,深路径(包名/types、包名/dist/types)又被 exports map 关掉,消费者没有任何合法途径 import 到那个接口。顺带说明门禁现状:
src/__tests__/templates.test.ts:177只断言src/types.ts在文件映射里存在,不断言它可达;#3733 加的 "import nothing the generated package.json does not declare" 是单向的(禁未声明的 import,不查未被使用的产物),这与 #3755 指出的同一个盲区。影响(如实说:今天没有东西是红的)
生成产物的 build 和 test 都不碰它,所以没有任何命令会因此失败 —— 属 observation 级,故打
finding、不排队。真正的成本在契约面:schema 接口正是元数据作者与渲染器之间的契约,脚手架生成了一份却让它不可达,作者要么以为已经导出、要么在自己的代码里重写一遍。有一点值得记下来:被 #3715 删掉的那页旧文档虚构的 entry 形状里写的是
export * from './types'—— 那句虚构恰好比真实模板更合理,这也是为什么它当年读起来没人起疑。可选方向(不预设结论)
export * from './types';—— 让脚手架自带的契约真的可达,改动最小。src/types.ts—— 既然无人 import,按「声明即使用」更干净,Props 接口(已在 Impl 导出)成为唯一契约面;与 create-plugin 生成产物的 dependencies 里lucide-react: '^0.563.0'被钉死在 0.563.x(仓内 23 处均为^1.28.0),且没有任何生成的源文件 import 它 #3755 的方向 2 同一取向。exports里加一条./types子路径 —— 成本最高、收益最小。倾向 1 或 2,分歧点是「脚手架是否应当预置一个 schema 类型面」这个产品判断,该由维护者定。
同族与串行
与 #3742(PR #3754,生成产物 devDependencies 锚定)和 #3755(生成产物
dependencies的lucide-react)同族、同文件(templates.ts),但三者范围互不覆盖:那两条是清单条目,这一条是源文件与exports面。落地时需与它们串行,避免同文件三方冲突。Generated by Claude Code