Uh oh!
There was an error while loading. Please reload this page.
fix(layout): declare the load-time registration in sideEffects (#3899) - #3940
Merged
Conversation
`packages/layout/package.json` declared `"sideEffects": false` while `src/index.ts` registers six component keys as a module load side effect. A bundler honouring the manifest is right to delete a side-effect-only `import '@object-ui/layout';` — measured with the repo's own bundler, the resulting bundle is 0 bytes with zero registrations, on a green build with no warning. Narrow the declaration to the modules that actually register, derived from the manifest's own entry fields plus the workspace source alias two in-repo consumers bundle through: ["./dist/index.js", "./dist/index.umd.cjs", "./src/index.ts"] The auto-registration itself is deliberately untouched; replacing it with an explicit API is the opposite direction and is left to the maintainer. Adds a build-level pin that runs a real bundler per entry form and asserts the registrations survive, each with a `sideEffects: false` control asserting they are dropped, so the pin cannot pass over a bundler that stopped shaking. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GTRjn8xBqp75dk7kFupVRt
The latest updates on your projects. Learn more about Vercel for GitHub. |
Contributor
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
…ader The file header repeated objectui#3899's own slip — it listed a `sidebar-nav` key this package has never registered. The six real keys are `page-header`, `page:card`, `app-shell`, `responsive-grid`, `navigation-renderer` and `app-schema-renderer`; the assertion already reads them out of `src/index.ts` rather than trusting a written list, which is why the prose was the only place the mistake survived. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GTRjn8xBqp75dk7kFupVRt
Contributor
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
yinlianghui
commented
Aug 9, 2026
CollaboratorAuthor
✅ 验收通过(objectui 分片 PM,session 实物核验:head Generated by Claude Code |
yinlianghui
marked this pull request as ready for review
August 9, 2026 13:45
Uh oh!
There was an error while loading. Please reload this page.
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 freeto 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#3899
执行 PM 裁决(评论 5229248921):只让清单说真话 ——
sideEffects从false收窄为点名含注册副作用的模块。⛔ 本单不动自动注册本身(「删自动注册改显式 API」语义相反、且对所有消费者破坏,留给维护者另立卡);⛔ 未碰apps/site(#3904 的面)。前提复核(origin/main @ 230ffd8)
两个锚点逐字存在:
packages/layout/package.json:5是"sideEffects": false,packages/layout/src/index.ts尾部是裸的try { registerLayout(); } catch {}。premise 成立。一处需要更正的细节:issue 正文说注册的是
page-header / app-shell / sidebar-nav,但本包从来没有sidebar-nav这个 key ——SidebarNav组件是以navigation-renderer进注册表的。实际六个 key 是page-header、page:card、app-shell、responsive-grid、navigation-renderer、app-schema-renderer。钉子里的 key 列表因此改成从src/index.ts现读而不是手写,正是为了不把这类笔误写成断言。实测圈定(本单交付要求 1)
先构建再以发布 tarball 会包含的文件为准,而不是照 issue 正文的
dist/index.js猜:npm pack --dry-run的 14 个文件里,JS 只有两个 ——dist/index.js(39.5kB)和dist/index.umd.cjs(32.0kB);其余是*.d.ts(类型声明会被擦除,不构成副作用面)、README / CHANGELOG / LICENSE / package.json。files只发dist,src不在 tarball 里。vite.config.ts的 lib 构建带inlineDynamicImports: true,所以不存在第三个 chunk 要点名。两个 JS 产物尾部都实测带着注册副作用(
index.js是try { nt(); } catch {},index.umd.cjs是try{$()}catch)。最终值:
三条都是 load-bearing,且集合是从清单自身推导的(
main/module/exports的 import+require 指向的全部 JS 文件),不是手列:./dist/index.js、./dist/index.umd.cjs—— 发布产物的全部入口形态。./src/index.ts—— 不发布,但真的被打包。apps/console/vite.config.ts:122与examples/console-starter/vite.config.ts都把 specifier 直接 alias 到packages/layout/src,打包器对这些文件读的是同一份清单。这一条是实测出来的、不是推的:只声明两个发布路径时,console 的 alias 形态依然产出 0 字节的 bundle。发布不是唯一的消费面 —— 漏掉它等于 apps/console 原样留着这个 bug。防回归钉:真打包器实测(交付要求 2)
packages/layout/src/__tests__/side-effects-manifest.test.ts,用仓内的 vite 8 / rolldown 1.2.1 以编程方式 build 一个只有import '@object-ui/layout';(纯副作用引入)的 entry,逐个入口形态断言注册存活;每个形态配一条sideEffects: false的对照断言注册被摇掉 —— 没有对照,上面全绿也可能只是「打包器根本没在摇」,即「因为什么都没产出所以断言通过」。write: false常驻内存,冷启 ~250ms、热 ~40ms,就是一条普通单测的成本。修前/修后,对真实构建产物、经 bare specifier 走 node 解析(
packages/app-shell/node_modules/@object-ui/layout→exports.import→dist/index.js):sideEffects: false反向核验(把清单改回
false跑新钉子)方向与预期一致:红。8 条里 4 红 4 绿,红的正好是清单推导 + 三个入口形态的存活探针,报的都是expected '' to contain …—— 空字符串,即 0 字节 bundle 本身:绿的 4 条正是该绿的:三条
false对照(它们自己就强制false,与清单无关)+declaresLoadTimeRegistration(源码侧不变量)。有一处我先写进测试、随后实测证伪并改掉的说法:我原本写「探针检查的是拼法」。实测
./dist/index.js、dist/index.js、dist/*.js、双星号/index.js四种拼法在 rolldown 下全部命中同一文件。所以探针对拼法并不敏感,红只意味着「这条路径根本没被覆盖」或「打包器改了对该字段的处理方式」,绝不是少个./的格式问题 —— 失败信息与文件头注释都按实测改成了这个说法。与另一张卡的关系(钉在测试里)
declaresLoadTimeRegistration断言src/index.ts仍在加载期调用registerLayout()。它不是在保卫这个副作用,而是保卫不变量:清单与模块体必须同时为真。若维护者后续采纳「改显式注册 API」,这条会变红 —— 那是故意的,它的意思是「另一半也要改」(那时诚实的清单又是false,本文件应随同一次改动删掉),而不是「把自动注册加回来」。失败信息里写明了这一点。验证
pnpm exec vitest run packages/layout/ --maxWorkers=2→ 7 files / 100 tests passed(新增 8 条)pnpm exec turbo run type-check --concurrency=2→ 78 successful, 78 totalpnpm --filter @object-ui/layout lint→ 0 errors(43 条既有 warning,新文件 0 条)pnpm --filter @object-ui/layout build→ 绿;产物仍为dist/index.js+dist/index.umd.cjs两个 JSnode scripts/check-control-bytes.mjs→ OK;改动文件另做了越过该 gate 的自扫(grep -naP覆盖 0x00-0x1f 全段)零命中changeset
.changeset/layout-sideeffects-registration-3899.md—— patch@object-ui/layout,正文写明这是打包契约修正:清单曾对打包器撒谎,修后sideEffects是最窄的诚实答案(而不是true,那样虽诚实却把整包交给所有打包器当不可摇)。README 补了一节 Registration,把「import '@object-ui/layout';即注册」写成受支持的入口点并指明是sideEffects在兜着。🤖 Generated with Claude Code
https://claude.ai/code/session_01GTRjn8xBqp75dk7kFupVRt
Generated by Claude Code