Uh oh!
There was an error while loading. Please reload this page.
fix(site): Playground 注册 layout 组件,并删掉两个非依赖的 transpilePackages 死条目 - #3942
Merged
Conversation
… transpilePackages entries The docs site has four SchemaRenderer hosts. objectui#3787 added `registerLayoutBlocks` to the three that render catalog examples; the Playground renders hand-typed schemas and was outside that acceptance surface, so typing `page-header` there still produced the red OBJUI-001 "Unknown component type" panel for a component the rest of the site renders fine. The placeholder net does not catch it either: `page-header` is in the opt-in PROTOCOL_COMPONENTS of `placeholders.tsx`, and `registerPlaceholders()` is only called by apps/console. Also removes `@object-ui/i18n` and `@object-ui/plugin-aggrid` from `apps/site`'s `transpilePackages`. Next resolves each entry as `<pkg>/package.json` FROM THE APP DIRECTORY to decide what to bundle rather than externalize, then matches by directory prefix; under pnpm's strict linker neither package is resolvable from apps/site (MODULE_NOT_FOUND, versus ERR_PACKAGE_PATH_NOT_EXPORTED for the real dependencies), so both entries did nothing while reading as if the site already supported those packages -- the same shape `@object-ui/layout` had before #3787. `packages/plugin-aggrid` no longer exists at all. The remaining 19 entries do resolve and therefore do work. The new gate test pins both faces, discovering the hosts rather than hardcoding four, since the bug was a host nobody remembered to add.
The latest updates on your projects. Learn more about Vercel for GitHub. |
…mputing it No behaviour change: the describe body already computes the host list for the zero-hit guard, so the parameterised case can take that array rather than walking apps/site/app a second time.
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:46
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#3904
背景
文档站有 4 个 SchemaRenderer 宿主。#3787 给渲染 catalog 示例的三个加了
registerLayoutBlocks,第四个 —— Playground —— 渲染的是用户手输的 schema,不在那次验收面内,于是今天在 Playground 敲一个page-header仍然得到红色 OBJUI-001「Unknown component type」面板,而文档站其它地方都能渲染它。占位符也接不住:page-header属于placeholders.tsx里 opt-in 的PROTOCOL_COMPONENTS,不在 eager 注册的PALETTE_PLACEHOLDER_BLOCKS里,而registerPlaceholders()只有apps/console调。同时
apps/site/next.config.mjs的transpilePackages列着两个非依赖包:@object-ui/i18n与@object-ui/plugin-aggrid。改动(三个文件)
apps/site/app/playground/page.tsx:模块作用域 import@/app/components/registerLayoutBlocks,与另三个宿主同款。用@/app/...别名而非相对路径,是跟随该文件既有的 provider import 写法(相对路径在app/playground/下拼出来反而不同)。apps/site/next.config.mjs:删掉两个死条目,并把「每一项都必须是本 app 已声明的依赖」连同原因写进注释。scripts/__tests__/site-playground-layout-registration-3904.test.ts:把两个面都钉住。两个条目为什么确实是死的(自行核实,不是照抄 issue)
Next 有两处消费
transpilePackages:webpack-config.js里建的node_modules/(名字)/路径正则;handle-externals.js里按名字把每一项解析成包名 + /package.json,解析起点是 app 目录;解析成功才记下该包目录,之后按目录前缀判定资源要 bundle 而不是 externalize。pnpm 严格 linker 下这两个包在
apps/site根本解析不到 —— 实测MODULE_NOT_FOUND,而真实依赖给的是ERR_PACKAGE_PATH_NOT_EXPORTED(找到了包,只是 exports 不暴露 package.json),两者可以干净地区分开。解析不到 ⇒ 不记目录 ⇒ 退回node_modules/名字/子串匹配,而 workspace 包的真实路径是packages/xxx/dist/...(webpacksymlinks: true),也命不中。两条路径都没有,条目零作用。packages/plugin-aggrid更是整个 workspace 里已经不存在了。反过来说,剩下 19 项是有作用的:它们能解析到,于是走目录前缀匹配,确实阻止了 externalize。所以这不是「整个数组都是装饰」,只有那两项是死的。
@object-ui/i18n那一项当初是「有意加的」,所以单独交代为什么删它安全审阅时值得先看这一节。根
CHANGELOG.md:565明确说这一项是为修 SSR 预渲染报错而加:所以它不是「一行装饰」,不能凭 issue 的说法一删了之。查证结果:
c4489d0fa(2026-03-31)。那个 commit 对 site 只改了next.config.mjs这一行,没有同时把@object-ui/i18n加成apps/site的依赖 —— 有意思的是同一个 commit 给 console 补的是真依赖(plugin-chatbot),正好是 site 这半边漏掉的那一步;git log -S '"@object-ui/i18n"' -- apps/site/package.json零命中:它从来没有做过apps/site的声明依赖;shouldIncludeExternalDirs早已是开着的,所以这一行唯一可能生效的路径就是「按名字解析」,而那条路径在 pnpm 严格 linker 下解析不到。实证:删掉该项后完整
next build预渲染 556/556 页全绿,其中 CHANGELOG 点名的那一页照常产出 ——.next/server/app/docs/components/overlay/tooltip.html,133KB 真实内容(Tooltip正文在内),dynamic usage of require零命中。也就是说那个报错并不靠这一项压着。一处相关细节:
@object-ui/i18n其实是components/react/fields的传递依赖,代码确实进了站点产物 —— 但它一直走的是真实路径packages/i18n/dist/*.js,本来就不靠这个条目;真正让 workspace 外部目录能被编译的是「transpilePackages数组非空」这个布尔,删两个名字后数组仍有 19 项,不受影响。这一点也写进了测试。验收 ②:剩余条目逐一核实
19 项全部是
apps/site/package.json的dependencies,且apps/site/node_modules/@object-ui/下都有 symlink:core、components、fields、layout、react、types、plugin-calendar、plugin-charts、plugin-chatbot、plugin-dashboard、plugin-editor、plugin-form、plugin-gantt、plugin-grid、plugin-kanban、plugin-map、plugin-markdown、plugin-timeline、plugin-view。这条核实已经机械化,不用下次再手数一遍。验收 ①:验证层级(如实报告)
apps/site没有任何测试基建 —— 无testscript、无 vitest config,且根 vitest 的sharedExclude直接排除apps/**。容器里也没有装 Playwright 浏览器(~/.cache/ms-playwright不存在),所以没有做真浏览器手敲那一步。按 issue 允许的下限做,并额外补了一层构建实证:静态断言(新测试,11 个 case 全绿):注册链三段接上 —— Playground import 了 registrar;registrar 从
@object-ui/layoutimport 并在模块作用域调用registerLayout()(该包sideEffects: false,只 import 不调用可能被摇掉);而registerLayout()真的注册page-header这一段,已经由packages/layout/src/__tests__/page-header-authorable-keys.test.tsx钉在实现旁边,这里不重复(那个文件是它的归属,且 packages/layout:sideEffects: falsecontradicts the load-timeregisterLayout()— a side-effect-only import can be tree-shaken away #3899 正在动那个包)。宿主是发现式枚举的,不是硬编码四个 —— 这个 bug 本来就是「谁都没想起来加的那个宿主」,第五个宿主会被同样地抓住。构建差分实证:
pnpm --filter @object-ui/site build两次(有/无本次 import),拿预渲染/playground页面实际引用的 chunk 去查只属于registerLayout的标记:responsive-grid105kecdsogrnc.jsnavigation-renderer105kecdsogrnc.jsapp-schema-renderer105kecdsogrnc.js顺带说明一个容易被误读的现象:光查
page-header字符串在两个构建里都命中一个 chunk —— 那是placeholders.tsx里 opt-in 名单的字符串,不是注册。所以差分用的是上面三个只出现在registerLayout里的标记;构建也证明sideEffects: false没有把它摇掉。反向验证(方向先判后跑,两边都是预期的红):去掉 Playground 那行 import,新测试点名
apps/site/app/playground/page.tsx变红、另三个宿主保持绿;把@object-ui/i18n放回transpilePackages,另一组点名它变红。一个值得维护者知道的点
pnpm type-check(turbo run type-check)覆盖不到本 PR 改的任何文件:apps/site的脚本叫types:check(不是type-check),scripts/也不是 workspace 包。所以除了全仓 78/78 全绿之外,另外单跑了pnpm --filter @object-ui/site types:check与pnpm type-check:scripts,都是 0 错。这是既有且登记过的状况(scripts/check-type-check-coverage.mjs绿,把它算作「1 not compiled」),不是本 PR 引入的,所以没有另开 issue。顺手记录的仓外发现
已另开 #3944(
finding标签,未认领):根vitest.config.mts的 alias 表有 4 个指向不存在目录的死条目(@object-ui/engine、@object-ui/renderer、@object-ui/plugin-aggrid、@object-ui/ui),是同一类「配置声明了、依赖图里没有」的漂移。实测这 4 个 specifier 的 import 数都是 0,今天没人碰到,所以按观察类记录、不在本 PR 修(vitest.config.mts是共享热文件)。不在本单内
「Playground 组件覆盖面到哪为止」按分诊定界可分割:它现在也没有
plugin-detail,所以record:*全渲染不出。那是 Playground 调色板的产品决定,不是这次的注册缺口,本 PR 不碰;packages/layout也没碰(#3899 的面)。changeset
不需要。
@object-ui/site在.changeset/config.json的ignore列表里(changesets 从不给它发版),另一个改动是scripts/__tests__/,不属于任何已发布包的src/。node scripts/check-changeset-presence.mjs输出:No source of a released package changed in this range, so no changeset is owed.🤖 Generated with Claude Code
https://claude.ai/code/session_01GTRjn8xBqp75dk7kFupVRt