Skip to content

docs(plugin-view): README 按真实导出面重写虚构的 viewComponents 手动注册,ObjectViewSchema 改从 @object-ui/types 导入 - #5078

Merged
yinlianghui merged 1 commit into
mainfrom
claude/issue-5014-plugin-view-readme
Aug 17, 2026
Merged

docs(plugin-view): README 按真实导出面重写虚构的 viewComponents 手动注册,ObjectViewSchema 改从 @object-ui/types 导入#5078
yinlianghui merged 1 commit into
mainfrom
claude/issue-5014-plugin-view-readme

Conversation

@yinlianghui

Copy link
Copy Markdown
Collaborator

Fixes#5014

基线 origin/main @ e6cd3c26c9ee3c64d76b5e18ab8b41a4aaa09c97(worktree 显式建在该 sha 上)。方法学照抄同族已落地的四单:#5010 → PR #5046#5016 → PR #5053#5012 → PR #5059#5015 → PR #5069

前提验证:卡面两条读数自己复测,都成立

卡面复核命令写的是裸 grep,按 #5012 的教训补词边界重测:

grep -rn "\bviewComponents\b" --include=*.ts --include=*.tsx --include=*.md packages apps
-> 唯二命中就是 README 自己(:41、:45)。src 零命中,全仓零命中。
grep -rn "\bObjectViewSchema\b" packages/plugin-view/src
-> 命中全在 __tests__ 与 src/ObjectView.tsx:27,且全部是 `from '@object-ui/types'` 的
import 或用法;src/index.tsx 零命中(未 re-export)。

零命中用邻近词反查:同一套核对里 ObjectView 命中导出面(src/index.tsx:18),所以 viewComponents 的零命中不是工具没跑起来。

判定表

README(改前)判定依据处理
:41import { viewComponents } + :45Object.entries(viewComponents).forEach(…)纯虚构全仓词边界零命中;39 个导出名里没有它删虚构节,改教真实机制
:337import type { ObjectViewSchema } from 本包真名,路径错真身 packages/types/src/objectql.ts,从 @object-ui/types 导出;本包只 import(src/ObjectView.tsx:27)不 re-export改导入路径 —— ⛔ 未加 re-export
:339-344 该 typed 示例的键面(object / viewMode / fields)真类型,键面漂移object 不是声明成员(真名 objectName,必填);viewMode / fields 亦非声明成员随导入路径一并对齐(见下「为什么这一处必须一起改」)

未新增任何导出、re-export 或类型来把 README 变真。

删掉的每一节,删因一行

  • ### Manual Registration 整节(改前 :38-48) —— 它教的 viewComponents 不存在,读者复制的第一行就是 Object.entries(undefined) 抛 TypeError;而它想表达的「注册」根本不需要手动做,是 import 入口的副作用。替换为三节真话:七个 register 调用认领的 schema 类型键表、本包 39 个真实导出名、以及原片段真正想做的事(把导出组件挂到自定义键)。

为什么 typed 示例的键面必须跟着一起改(而不是夹带)

改前那个示例被 ObjectViewSchema 标注,但因为导入失败、标注是 error type,键面从不被判。把导入路径修对的同时,这三个键就第一次落到了编译面上:object 不是声明成员且真名 objectName 必填 —— 不改示例就编译不过。这与 #5059GanttTask 那一处同形。

名集合核对读数

导出名集合取自构建产物dist/index.d.ts,走 TS compiler API 的 checker.getExportsOfModule;README 侧不用正则抓 import —— 先抽 fenced 块,每块 ts.createSourceFile,再走 ImportDeclaration 的 AST,A as BpropertyName(导出名)而非本地别名。#5043 记的两个坑因此在结构上不可能发生。

export surfaces: @object-ui/plugin-view 39 / @object-ui/types 675 /
@object-ui/core 416 / @object-ui/data-objectstack 72
改前: 18 个 fenced 块 / 4 bindings / MISSING COUNT: 2
- viewComponents from @object-ui/plugin-view @ README.md:41
- ObjectViewSchema from @object-ui/plugin-view @ README.md:337
改后: 19 个 fenced 块 / 43 bindings / MISSING COUNT: 0

改后 43 个绑定逐个 OK,其中新增的两个多行 import 块覆盖本包全部 39 个导出名(24 值 + 15 类型),核对因此不再只是抽样。

编译探针读数

README 的 ts/tsx 块抄进 scratch,对同一批构建产物编译(strict: true,没有为让块通过而放松任何选项);块按内容签名分类而非块序号,所以改前改后共用一套机器。

改前: 14 个可编译块(4 块按设计跳过并列明理由) tsc -> rc=2
block02(1,10): error TS2305: Module '"@object-ui/plugin-view"' has no exported member 'viewComponents'. [README:41]
block18(1,15): error TS2305: Module '"@object-ui/plugin-view"' has no exported member 'ObjectViewSchema'. [README:337]
block08(7,14) / block10(8,20) / block12(9,20) / block12(9,24) / block13(8,20): TS7006 (既有)
改后: 15 个可编译块(4 块按设计跳过) tsc -> rc=2
block09(7,14) / block11(8,20) / block13(9,20) / block13(9,24) / block14(8,20): TS7006 (原样携带)

跳过的四块(输出里列明,不静默丢)::135 / :153 / :172 / :193 的 Schema API 形状速写 —— object: string / views: [...] 这类类型语法落在值位置或裸字面量,故意不合法的 TS。

剩下的 5 条 TS7006 不是本 PR 的漏修:是 CRUD 四段里 onCreate: async (data) => … 写在无类型标注的 const schema = { … } 里,属那一族虚构 schema 键的一部分。改前改后逐条一一对应、坐标与文本完全相同(README 行号各 +79,即本 PR 的插入量):

改前改后README(前 → 后)
block08.ts(7,14)block09.ts(7,14):148:227(Form View)
block10.ts(8,20)block11.ts(8,20):179:258(Create)
block12.ts(9,20)block13.ts(9,20):209:288(Update)
block12.ts(9,24)block13.ts(9,24):209:288(Update)
block13.ts(8,20)block14.ts(8,20):225:304(Delete)

逐键 pin(改后示例的键面不靠外推)

散文与示例新增的断言单独钉在真类型上,一文件一键(多余属性会短路其余诊断 —— #5059 / #5069 都记过):

钉的内容诊断
{ type: 'object-view', object: 'users' }TS2741: Property 'objectName' is missing … but required in type 'ObjectViewSchema'
{ …, viewMode: 'grid' }rc=0,无诊断
{ …, fields: ['name'] }rc=0,无诊断
改后示例(objectName / defaultViewType / table.columns)rc=0,无诊断

中间两行是本 PR 最该被读到的一条读数,如实记:viewMode / fields 这两个虚构键 tsc 不报。原因是结构性的 —— ObjectViewSchema extends BaseSchema,而 BaseSchema[key: string]: any(packages/types/src/base.ts:318),excess property 检查整体失效。也就是说编译探针在这个类型上唯一有牙的是「必填 objectName 缺失」;虚构键这一整类,这道门天生看不见。若不写下来,下一个读者会误以为「改后探针绿」等于「键面已被验证」。这条同时是下面 #5077 立卡的核心依据。

反向验证(两条,预判先写)

(a) 名集合核对自证。 预判:MISSING COUNT 0 → 2;别名判导出名;行尾注释里的非导出词不得报。四条全符 ——

变异预判实测
多行导入块中段viewComponents,viewComponents @ :87
多行类型导入块中段插 ViewThings as Things报,且按导出名ViewThings 而非别名 ThingsViewThings @ :112
ViewSwitcherViewSwitcher as Switcher仍 OK(别名判导出名)OK @ :73
行尾 // viewComponents was never real不得报(假阳性测试)未报,该行 ViewTabBar 仍 OK @ :77

MISSING COUNT: 2,还原读数 0。变异全做在 README 的 scratch 副本上(检查器的 --readme 指向副本),git status --porcelain 全程只有本卡那两个条目 —— 不存在「临时改动误入 commit」的窗口。

(b) 改前 README 回填探针。 预判(先写):必须转红;新增诊断恰好两条、与所改两处一一对应;5 条既有 TS7006 原样携带;并且 —— 改前 typed 示例的坏键(object / viewMode / fields)不会贡献诊断,因为导入失败会把标注变成 error type、把键面遮蔽掉。

实测与预判完全一致(读数见上表)。第四条预判尤其要记:它意味着「改前红 / 改后绿」这条线由两个 TS2305 承载;键面那一层从来没有被探针覆盖过,是改对导入路径之后才第一次可判 —— 这也是为什么键面对齐必须与路径修改同一 commit,以及为什么剩下 13 个无标注块的键面只能另立卡(#5077)。

方向即通常的「改前红 / 改后绿」,不适用 ?? 链、计数门那类反转情形(这是导入名不存在,不是取值判决)。

验证

  • 仓根 pnpm exec turbo run type-check --concurrency=281 successful, 81 total(4m9s;重活经 flock -w 3600 /tmp/os-heavy-verify.lock 串行 + --max-old-space-size=4096)。
  • node scripts/check-doc-links.mjsLinks are valid across 13 scan roots.
  • node scripts/check-control-bytes.mjsOK (scanned 4516 tracked text file(s); skipped 85 binary);改动两文件另做 grep -naP '[\x00-\x08\x0b\x0c\x0e-\x1f]' 自扫,零命中。
  • pnpm --workspace-concurrency=2 --filter '@object-ui/plugin-view...' build → rc=0(探针与名集合核对所依赖的构建产物)。

docs-only 的 CI 形状:**/*.md.changeset/**paths-ignore 里,Test / Type Check 各 job 的实质步骤会被 path-filter 短路成 skipped 而 job 报 success。按纪律计绿,但类型证据是上面的本地仓根读数,不是 CI 的(#5046 / #5053 / #5059 / #5069 先例)。

顺手立的卡(未认领,不夹带进本 PR)

顺带记入本 PR(不另立卡,是 README 新增内容的一部分):本包的注册命名空间不统一 —— object-view / view / view:simpleplugin-view,四个控件用 view;view:simple 因带命名空间实际落成 plugin-view:view:simple。都已按实际读数写进新表,未做任何改动主张。

changeset

.changeset/plugin-view-readme-truth-5014.md,@object-ui/plugin-view: patch,口径同 #5046 / #5053 / #5059 / #5069:无代码/类型/运行时改动,声明 patch 是因为 README.md 在包的 files 里,随下次发布到 npm。


Generated by Claude Code

…chema 改从 @object-ui/types 导入
`### Manual Registration` 教的 `viewComponents` 在本包乃至全仓零命中(唯二命中就是
README 自己),照抄第一行即 `Object.entries(undefined)` 抛 TypeError。删掉该虚构节,
换成三节真话:七个 `ComponentRegistry.register` 调用认领的 schema 类型键表(含
`Registry.ts:195,240` 的命名空间键 + 裸 type 回落)、本包 39 个真实导出名、以及原片段
真正想做的事(把导出组件挂到自定义键)。
`ObjectViewSchema` 是真类型,但声明在 `@object-ui/types`(`objectql.ts`),本包只
import(`src/ObjectView.tsx:27`)不 re-export,按 README 原路径导入是 TS2305。修法是改
导入路径,⛔ 未新增任何导出或 re-export。改路径后示例的键面成为编译面上的断言,故随之
对齐真身:`objectName` 必填(`object` 不是声明成员)、`defaultViewType`、
`table.columns`。
其余未加类型标注的 schema 字面量键面(`object` / `viewMode` / `fields` / `mode` /
`recordId` / `fieldConfig` / `nestedFields` / `tabs` …)渲染器一个都不读,性质不同、
需独立定级,另立卡不夹带。
Co-authored-by: Claude <noreply@anthropic.com>
@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation plugin labels Aug 17, 2026
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Main entry (gzip)25.3 KB350 KB
Entry fileindex-TJ-eodDQ.js
StatusPASS

📦 Bundle Size Report

PackageSizeGzipped
app-shell (index.js)9.56KB3.59KB
app-shell (runtime-config.js)7.42KB2.32KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)8.92KB3.41KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)1.17KB0.53KB
auth (AuthProvider.js)25.13KB5.40KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.13KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.64KB2.21KB
auth (SocialSignInButtons.js)9.60KB3.89KB
auth (UserMenu.js)3.40KB1.22KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.79KB
auth (createAuthenticatedFetch.js)6.34KB2.43KB
auth (index.js)2.71KB1.22KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.02KB0.88KB
auth (useIsWorkspaceAdmin.js)1.61KB0.85KB
collaboration (CommentThread.js)26.07KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.65KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)502.20KB112.21KB
core (index.js)4.11KB1.62KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)159.03KB44.08KB
fields (index.js)234.25KB58.48KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (currency.js)1.22KB0.64KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.35KB1.38KB
i18n (pickLocalized.js)3.69KB1.73KB
i18n (provider.js)23.12KB7.62KB
i18n (useDisplayLocale.js)2.84KB1.45KB
i18n (useObjectLabel.js)27.59KB6.63KB
i18n (useSafeTranslation.js)7.77KB3.13KB
layout (index.js)39.16KB10.97KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.74KB
mobile (index.js)1.50KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.71KB0.42KB
mobile (useResponsiveConfig.js)1.36KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)9.35KB3.31KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)4.42KB1.42KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.91KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.52KB
permissions (usePermissions.js)1.81KB0.83KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)46.62KB12.83KB
plugin-charts (index.js)64.75KB18.37KB
plugin-chatbot (index.js)181.21KB43.14KB
plugin-dashboard (index.js)127.85KB32.73KB
plugin-designer (index.js)212.39KB42.83KB
plugin-detail (index.js)241.12KB60.43KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)123.10KB29.84KB
plugin-gantt (index.js)164.10KB39.87KB
plugin-grid (index.js)197.61KB53.03KB
plugin-kanban (index.js)52.72KB14.54KB
plugin-list (index.js)111.17KB26.99KB
plugin-map (index.js)18.72KB6.09KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)41.97KB11.33KB
plugin-timeline (index.js)26.68KB7.66KB
plugin-tree (index.js)8.50KB2.88KB
plugin-view (index.js)83.81KB20.49KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.44KB0.22KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)3.77KB1.33KB
react (SchemaRenderer.js)27.53KB9.41KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)1.28KB0.68KB
react (schema-input.js)1.45KB0.83KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (index.js)4.77KB2.16KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)10.76KB3.17KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.29KB0.24KB
sdui-parser (validate.js)6.92KB2.40KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)0.20KB0.18KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)0.20KB0.18KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.87KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-retry.js)4.32KB2.02KB
types (index.js)3.05KB1.52KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)2.59KB1.31KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)0.20KB0.18KB
types (ui-action.js)3.40KB1.71KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

  • ✅ Core packages should be < 50KB gzipped
  • ✅ Component packages should be < 100KB gzipped
  • ⚠️ Plugin packages should be < 150KB gzipped

@yinlianghuiClaude

Copy link
Copy Markdown
CollaboratorAuthor

PM 验收:ACCEPT(session session_01GTRjn8xBqp75dk7kFupVRt,objectui 分片 PM,批次 22)

实物核验:merge-base e6cd3c26c,2 files +117/−9 与报告一致,单 commit,模型标识 msg/diff 双零,releases 零触碰,⛔ 零新导出/零 re-export。CI 亲读:19 个 check-run 全 completed 零失败(docs-only 形状,类型证据本地 81/81)。

验收要点:

  1. typed 示例键面的「计入本卡」判定采信:改路径后失败导入不再把标注变 error type,键面第一次落到编译面 —— object 非声明成员且真名 objectName 必填,不改就编译不过;与 :337 同块、同 commit、判定表单列理由。这不是夹带,是修法的必然连带。
  2. 第四条预判命中且价值独立:改前坏键零诊断的机理(error type 遮蔽)被明确记录 —— 「改前红/改后绿」只由两条 TS2305 承载,键面从未被探针覆盖。这与逐键 pin 的诚实读数(viewMode/fields 钉真类型仍 rc=0,BaseSchema 索引签名使 excess-property 检查整体失效,唯一有牙的是必填 objectName)一起,构成索引签名致盲的第三次独立确认(plugin-gantt README 教的整片 schema 键面渲染器一个都不读 —— tasks / viewMode / object / startField 全零命中,照抄即空图 #5057 席、plugin-dashboard README 的 TypeScript 一节导入 DashboardSchema / MetricCardSchema,两个名字在全仓都不存在 #5015 席之后)—— 未拿探针绿冒充键面证据,并把它作为 plugin-view README 整片 schema 键面渲染器一个都不读 —— object / viewMode / fields / mode / recordId / fieldConfig 全非声明成员,照抄即空视图 #5077 的核心依据。案头条目维持:授权 schema 键面证据只能靠读取点 grep。
  3. 39 名导出面全量写进两个多行 import 块「使核对不再是抽样」+ 命名空间键不统一的实测(view:simple 实落 plugin-view:view:simple)—— README 从愿望清单变成账本,同族最佳形。
  4. scratch 放会话 scratchpad 使「误入 commit」窗口不存在 —— 工位纪律的正确升级。

派生物分诊(本评论即记录):#5077(其余 13 个无类型标注块的键面,42 声明成员清单 + 读点计数 + 两道门天生盲的机理)→ pm:queue + bug + documentation,与本 PR 同文件、落 main 后再派(验证要求:cast 感知读取点 grep,同 #5057 重派口径)。

转 ready 并挂 auto-merge(squash)。


Generated by Claude Code

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationplugin

Projects

None yet

Development

Successfully merging this pull request may close these issues.

plugin-view README 教的 viewComponents 手动注册不存在,ObjectViewSchema 也不从本包导出

2 participants

@yinlianghui@claude