发现于 #4206 :那个 PR 要把 <包根>/scripts/** 排除出 docs-drift 的实现改动判定,落地前需要核实「有没有包把 scripts/ 当运行时代码发布」。核查 files 字段时发现了一个更广的打包卫生问题。
现状
仓库里 20 个非 private 包没有 files 字段 ,npm 因此按默认规则打包整个目录:
packages/formula @objectstack/formula
packages/sdui-parser @objectstack/sdui-parser
packages/connectors/connector-mcp @objectstack/connector-mcp
packages/connectors/connector-openapi @objectstack/connector-openapi
packages/connectors/connector-rest @objectstack/connector-rest
packages/connectors/connector-slack @objectstack/connector-slack
packages/plugins/embedder-openai @objectstack/embedder-openai
packages/plugins/knowledge-memory @objectstack/knowledge-memory
packages/plugins/knowledge-ragflow @objectstack/knowledge-ragflow
packages/plugins/plugin-approvals @objectstack/plugin-approvals
packages/plugins/plugin-email @objectstack/plugin-email
packages/plugins/plugin-pinyin-search @objectstack/plugin-pinyin-search
packages/plugins/plugin-reports @objectstack/plugin-reports
packages/plugins/plugin-sharing @objectstack/plugin-sharing
packages/plugins/plugin-webhooks @objectstack/plugin-webhooks
packages/services/service-cluster @objectstack/service-cluster
packages/services/service-cluster-redis @objectstack/service-cluster-redis
packages/services/service-datasource @objectstack/service-datasource
packages/services/service-sms @objectstack/service-sms
packages/triggers/trigger-api @objectstack/trigger-api
对照组:spec、objectql、platform-objects、plugin-audit、plugin-security、driver-sqlite-wasm、service-messaging、service-realtime、service-storage 都声明了 files(基本是 ["dist","README.md"]),所以这 20 个是漏了 ,不是有意的另一套约定。
实测
npm pack --dry-run on @objectstack/plugin-webhooks:
文件数: 21 | 分布: { src/: 15, scripts/: 1, 其他: 5 }
其中测试文件: 3
src/auto-enqueuer.test.ts
src/bootstrap-declared-webhooks.test.ts
...
scripts/i18n-extract.config.ts
即消费者装到的是 TypeScript 源码 + 单元测试 + 构建期工具配置 。(该检出未构建,所以 dist/ 未出现在列表里;真实发布时 dist/ 会在这些之上另加,不会替代它们。)
为什么值得修
体积与噪声 —— 测试文件对消费者零价值,却计入安装体积和依赖扫描面。
scripts/ 被发布是 fix(docs-audit): derive package roots from the filesystem, not a special-cased regex #4206 那条排除臂的唯一潜在反例。 目前结论仍成立 —— 这 20 个包里带 scripts/ 的三个(plugin-approvals / plugin-sharing / plugin-webhooks)装的都只是 i18n-extract.config.ts,是构建期工具而非运行时代码,所以「scripts/** 不算实现改动」没有被证伪。但这个结论是靠逐个人工核对内容 得到的,不是靠任何机制保证的:哪天有人往某个包的 scripts/ 放进运行时代码并发布,fix(docs-audit): derive package roots from the filesystem, not a special-cased regex #4206 的排除就会开始漏报,而没有任何东西会喊一声。
一致性 —— 一半包声明 files 一半不声明,是 排查「手抄 spec 清单 + "keep in sync" 注释」模式:一天内确认三例,全部曾静默漂移 #3786 那类「手抄清单没有闸门」的形状。
建议
给这 20 个包补 "files": ["dist", "README.md"](与已有包对齐;个别包若确实需要发布 src/ 做 source map 调试,单独说明并显式列出)。
真正治本的是加一道闸门,而不是补完这一轮就完事 —— 例如在 lint 阶段断言「每个非 private 包都必须声明 files」。仓库里 scripts/check-*.mjs 已经有一整套同形状的守卫可循,加一条的成本很低,且能顺带让 #4206 的那个假设从「人工核对过」变成「持续被校验」。
发现于 #4206:那个 PR 要把
<包根>/scripts/**排除出 docs-drift 的实现改动判定,落地前需要核实「有没有包把scripts/当运行时代码发布」。核查files字段时发现了一个更广的打包卫生问题。现状
仓库里 20 个非 private 包没有
files字段,npm 因此按默认规则打包整个目录:对照组:
spec、objectql、platform-objects、plugin-audit、plugin-security、driver-sqlite-wasm、service-messaging、service-realtime、service-storage都声明了files(基本是["dist","README.md"]),所以这 20 个是漏了,不是有意的另一套约定。实测
npm pack --dry-runon@objectstack/plugin-webhooks:即消费者装到的是 TypeScript 源码 + 单元测试 + 构建期工具配置。(该检出未构建,所以
dist/未出现在列表里;真实发布时dist/会在这些之上另加,不会替代它们。)为什么值得修
scripts/被发布是 fix(docs-audit): derive package roots from the filesystem, not a special-cased regex #4206 那条排除臂的唯一潜在反例。 目前结论仍成立 —— 这 20 个包里带scripts/的三个(plugin-approvals/plugin-sharing/plugin-webhooks)装的都只是i18n-extract.config.ts,是构建期工具而非运行时代码,所以「scripts/**不算实现改动」没有被证伪。但这个结论是靠逐个人工核对内容得到的,不是靠任何机制保证的:哪天有人往某个包的scripts/放进运行时代码并发布,fix(docs-audit): derive package roots from the filesystem, not a special-cased regex #4206 的排除就会开始漏报,而没有任何东西会喊一声。files一半不声明,是 排查「手抄 spec 清单 + "keep in sync" 注释」模式:一天内确认三例,全部曾静默漂移 #3786 那类「手抄清单没有闸门」的形状。建议
给这 20 个包补
"files": ["dist", "README.md"](与已有包对齐;个别包若确实需要发布src/做 source map 调试,单独说明并显式列出)。真正治本的是加一道闸门,而不是补完这一轮就完事 —— 例如在 lint 阶段断言「每个非 private 包都必须声明
files」。仓库里scripts/check-*.mjs已经有一整套同形状的守卫可循,加一条的成本很低,且能顺带让 #4206 的那个假设从「人工核对过」变成「持续被校验」。