Skip to content

docs(runner): README §Development Workflow 按两个 loader 的真相改写第 1、3 步 (#3604) - #3621

Merged
yinlianghui merged 1 commit into
mainfrom
claude/issue-3604-readme-json-only
Aug 7, 2026
Merged

docs(runner): README §Development Workflow 按两个 loader 的真相改写第 1、3 步 (#3604)#3621
yinlianghui merged 1 commit into
mainfrom
claude/issue-3604-readme-json-only

Conversation

@yinlianghui

Copy link
Copy Markdown
Collaborator

Fixes #3604

本正文里的尖括号占位符一律写成 pages/< route >.json 这样带空格的形式,只是为了绕开 GitHub 正文里 <+字母 会被当成 HTML 标签吞掉的存储行为。文件里的真实拼写不带空格,以 Files 页的 diff 为准。

前提复核(对 origin/main,616353ad1)

分诊已核过一轮,这里独立复核一遍,结论一致 —— 行号也没再漂:

改写前后对照

改前

1. Create a schema file (JSON or TypeScript)
2. Start the runner with `pnpm dev`
3. Edit the schema - changes reload automatically

改后(第 2 步未动)

1. Author the metadata as JSON — both loaders resolve fixed `.json` paths, and JSON is
   the only shape either of them can load. Pick one of the two routes described under
   [Metadata Loading](#metadata-loading):
   - **Bundled** — create `packages/runner/src/app-data/` and put `app.json` plus one
     `pages/< route >.json` per route in it (route `/` is `pages/index.json`). That
     directory is git-ignored, absent from a fresh checkout, and no script in this repo
     creates it, so making it is a step you do by hand — until it exists, every load
     returns nothing and the page renders as a 404.
   - **Served** — run a backend that answers `< base >/app.json` and
     `< base >/pages/< route >.json`, then open the runner with `?api=< base >`.
3. Edit the metadata. Under `src/app-data/` the dev server picks the change up without a
   restart, because that JSON is part of Vite's module graph; behind `?api=` it cannot,
   because Vite never sees your backend. Reload the page if the view still shows the
   previous document.

路径拼写与本文件 §Metadata Loading 一节对齐(app.json + pages/index.json 对应路由 /),该节的 ?api= 表格和 loader 的解析顺序都已经把这两种形状写清楚了,第 1 步现在指过去而不是另讲一套。

第 3 步:为什么是这样限定的(与派发预设有出入,如实说明)

派发要求「限定而非删除」,并预设 LocalBundleLoader 一侧「成立(Vite HMR)」。分路保留了,但成立那一侧我没有按「自动热更新」来断言,理由是脱离实跑无法从代码确认:

  • 可从代码确认的部分,已经写进正文:src/app-data/**/*.jsonimport.meta.glob 进入 Vite 的 module graph,dev server 会 watch 它 —— 所以改动不需要重启 dev server;而 ?api= 那条后端完全在 Vite 的视野之外,不存在任何 watch/reload 机制,这一侧的否定是无条件成立的。
  • 无法从代码确认的部分:更新最终是否会自己出现在屏幕上src/App.tsx 只导出组件(RunnerApp + 一个空的 export {}),因此是 react-refresh 的边界;JSON 变更沿 MetadataLoader.ts 冒泡到这个边界后,可能表现为整页 reload,也可能被一次保状态的重渲染吸收 —— 后者下 pageSchema 这个 useState 不变、useEffect 的依赖 [currentPath, loader] 也不变(loaderuseMemo(…, [])),重新读取不会发生,读者看到的仍是旧文档。判定这一点需要真起服务在浏览器里看,本任务的范围里不含实跑。

写一个未经确认的机制断言,正是本 issue(以及 #3533)要清除的那类东西,所以正文落在两种机制下都成立、且对读者可操作的说法上:「视图仍是旧文档就刷新页面」。如果维护者希望把这一句强化成明确的「自动刷新」,需要先起一次 dev server 实测,我可以另开一趟做。

验证

改动是单文件 markdown,如实写明每条证据的覆盖面:

命令 结果 覆盖面
node scripts/check-control-bytes.mjs ✅ OK (scanned 3650 tracked text file(s); skipped 85 binary) 覆盖本文件 —— 该脚本以 git ls-files -z 为扫描面
node scripts/check-doc-links.mjs Links are valid across 6 scan roots. 不覆盖本文件 —— SCAN_ROOTS(scripts/check-doc-links.mjs:286)是 content/docsexamplesREADME.mdCONTRIBUTING.mdROADMAP.mddocs,packages/** 不在其中。改前改后都绿,不构成对本改动的背书
grep -naP '[\x00-\x08\x0b\x0c\x0e-\x1f]' packages/runner/README.md 无输出(rc=1),改前的 blob 同样干净 门禁盲区自扫
grep -n 'TypeScript' packages/runner/README.md 仅剩 :170 - **TypeScript:** ≥ 5.0 (strict mode) §Development Workflow 节内 0 命中;残留那条在 §Compatibility,讲的是工具链版本要求,与 schema 的书写形式无关,合法保留

未跑 pnpm test / pnpm type-check,这是判断不是遗漏:改动是 markdown,不被任何代码路径导入,packages/runner 的测试也不读 README;仓库自己的 ci.ymllint.yml**/*.mdpaths-ignore,即本 PR 在 CI 上只会触发 control-bytes.yml(无 path 过滤)。为一个必然无关的结果去装一整棵 node_modules 并构建依赖,不符合共享容器的资源纪律。

无 changeset

#3602(同一文件、同样只改 README,1 file changed)先例一致:包 README 的文档修正不进 changeset。changeset-guard.yml 的触发条件是 paths: .changeset/**,不会因为缺 changeset 而红。

越界发现(未在本 PR 修改)

按派发要求通读了 §Development Workflow 全节,其余步骤无同类虚构,一并核过:第 2、5 步的 pnpm dev / pnpm buildpackages/runner/package.jsonscripts 里真实存在(vite / vite build);第 4 步是通用表述。顺带核了紧邻的 §Example Schema,其中 page / grid / card / statistic 四个组件类型在 packages/components/src/renderers/ 下均有对应 renderer,不是虚构,故未动。


🤖 Generated with Claude Code

https://claude.ai/code/session_01GTRjn8xBqp75dk7kFupVRt


Generated by Claude Code

…3604)

第 1 步「Create a schema file (JSON or TypeScript)」与本文件自己的
§Metadata Loading 直接矛盾:runner 没有任何路径能加载 TypeScript 写的
schema —— LocalBundleLoader 的三个 import.meta.glob 全是 `.json`
(MetadataLoader.ts:26-28),NetworkLoader 只 fetch 固定的 `.json` 路径
并直接 `res.json()`(同文件 89、101 行)。按 #3533 的口径(文档不许描述
实现里不存在的能力)改写成 JSON 的两条真实路线,并点名 `src/app-data/`
是 git-ignored、新检出下不存在、仓里没有任何脚本会创建它 —— 这正是照旧
文本操作的读者下一步会撞上的坑(每次加载返回 null,页面渲染成 404)。

第 3 步「changes reload automatically」按 loader 分路限定而非删除:
`src/app-data/` 下的 JSON 在 Vite 的 module graph 里,改动不需要重启 dev
server;`?api=` 那条 Vite 根本看不见后端。这里刻意没有断言浏览器会自动
刷新 —— App.tsx 只导出组件,是 react-refresh 的边界,更新可能被
保状态的重渲染吸收,而这一点脱离实跑无法从代码确认;写不确定的机制
断言正是本 issue 要清的那类虚构。改成「视图仍是旧文档就刷新页面」,
两种机制下都成立,且对读者可操作。

无 changeset:包 README 的文档修正,与 #3602(同一文件,同样只改 README)
先例一致;ci.yml / lint.yml 对 `**/*.md` 走 paths-ignore。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GTRjn8xBqp75dk7kFupVRt
@vercel

vercel Bot commented Aug 7, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectui Ignored Ignored Aug 7, 2026 4:09pm

Request Review

@github-actions github-actions Bot added the documentation Improvements or additions to documentation label Aug 7, 2026
@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Main entry (gzip) 28.1 KB 350 KB
Entry file index-DBwr6kyx.js
Status PASS

📦 Bundle Size Report

Package Size Gzipped
app-shell (index.js) 8.66KB 3.13KB
app-shell (runtime-config.js) 7.42KB 2.32KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 7.57KB 2.97KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 1.17KB 0.53KB
auth (AuthProvider.js) 22.10KB 4.37KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.13KB 5.39KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.64KB 2.21KB
auth (SocialSignInButtons.js) 9.60KB 3.89KB
auth (UserMenu.js) 3.40KB 1.22KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 35.76KB 9.11KB
auth (createAuthenticatedFetch.js) 4.37KB 1.69KB
auth (index.js) 2.35KB 1.07KB
auth (org-roles.js) 6.66KB 2.78KB
auth (phone-identifier.js) 1.11KB 0.66KB
auth (types.js) 0.59KB 0.35KB
auth (useAuth.js) 4.91KB 0.87KB
auth (useIsWorkspaceAdmin.js) 1.61KB 0.85KB
collaboration (CommentThread.js) 26.07KB 7.56KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.49KB 2.64KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.65KB 0.73KB
collaboration (useCollaborationTranslation.js) 6.05KB 2.52KB
collaboration (useCommentSearch.js) 1.98KB 0.88KB
collaboration (useConflictResolution.js) 7.75KB 1.86KB
collaboration (useMentionNotifications.js) 1.81KB 0.68KB
collaboration (usePresence.js) 6.33KB 1.84KB
collaboration (useRealtimeSubscription.js) 7.91KB 2.01KB
components (index.js) 480.72KB 105.64KB
core (index.js) 2.96KB 1.13KB
create-plugin (index.js) 9.28KB 2.98KB
data-objectstack (index.js) 137.51KB 35.11KB
fields (index.js) 230.87KB 56.83KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (currency.js) 1.22KB 0.64KB
i18n (i18n.js) 4.32KB 1.77KB
i18n (index.js) 2.65KB 1.06KB
i18n (pickLocalized.js) 1.70KB 0.83KB
i18n (provider.js) 9.48KB 3.27KB
i18n (useObjectLabel.js) 26.14KB 6.07KB
i18n (useSafeTranslation.js) 4.52KB 1.96KB
layout (index.js) 38.53KB 10.71KB
mobile (MobileProvider.js) 0.92KB 0.49KB
mobile (ResponsiveContainer.js) 0.94KB 0.38KB
mobile (breakpoints.js) 1.51KB 0.70KB
mobile (createOfflineDataSource.js) 5.61KB 1.74KB
mobile (index.js) 1.50KB 0.62KB
mobile (offlineQueue.js) 3.91KB 1.35KB
mobile (pwa.js) 0.97KB 0.49KB
mobile (serviceWorker.js) 1.48KB 0.62KB
mobile (serviceWorkerSource.js) 3.41KB 1.48KB
mobile (useBreakpoint.js) 1.54KB 0.65KB
mobile (useGesture.js) 6.96KB 1.98KB
mobile (useOfflineSync.js) 1.99KB 0.72KB
mobile (usePullToRefresh.js) 2.53KB 0.85KB
mobile (useResponsive.js) 0.71KB 0.42KB
mobile (useResponsiveConfig.js) 1.36KB 0.63KB
mobile (useSpecGesture.js) 4.32KB 1.64KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 8.75KB 3.06KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 3.67KB 1.12KB
permissions (evaluator.js) 4.41KB 1.44KB
permissions (index.js) 0.91KB 0.41KB
permissions (store.js) 0.91KB 0.42KB
permissions (useFieldPermissions.js) 1.28KB 0.52KB
permissions (usePermissions.js) 1.55KB 0.71KB
plugin-ai (index.js) 15.71KB 3.79KB
plugin-calendar (index.js) 44.98KB 12.37KB
plugin-charts (index.js) 61.04KB 17.31KB
plugin-chatbot (index.js) 180.09KB 42.72KB
plugin-dashboard (index.js) 115.50KB 29.96KB
plugin-designer (index.js) 210.51KB 42.51KB
plugin-detail (index.js) 232.79KB 57.42KB
plugin-editor (index.js) 2.46KB 1.10KB
plugin-form (index.js) 112.10KB 27.10KB
plugin-gantt (index.js) 162.55KB 39.57KB
plugin-grid (index.js) 186.61KB 49.34KB
plugin-kanban (index.js) 48.30KB 13.28KB
plugin-list (index.js) 105.12KB 25.48KB
plugin-map (index.js) 16.81KB 5.24KB
plugin-markdown (index.js) 13.72KB 4.69KB
plugin-report (index.js) 40.58KB 10.58KB
plugin-timeline (index.js) 25.76KB 7.33KB
plugin-tree (index.js) 8.50KB 2.88KB
plugin-view (index.js) 84.03KB 20.55KB
providers (DataSourceProvider.js) 0.75KB 0.39KB
providers (MetadataProvider.js) 1.37KB 0.59KB
providers (ThemeProvider.js) 1.90KB 0.85KB
providers (UploadProvider.js) 11.71KB 3.53KB
providers (index.js) 0.44KB 0.22KB
providers (types.js) 0.01KB 0.04KB
react-runtime (index.js) 5.67KB 2.37KB
react (LazyPluginLoader.js) 3.77KB 1.33KB
react (SchemaRenderer.js) 19.28KB 6.38KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 1.02KB 0.55KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (codegen.js) 4.09KB 1.74KB
sdui-parser (index.js) 4.47KB 2.03KB
sdui-parser (parse.js) 10.04KB 2.82KB
sdui-parser (types.js) 0.29KB 0.24KB
sdui-parser (validate.js) 4.69KB 1.48KB
types (ai.js) 0.20KB 0.17KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 2.87KB 0.99KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (complex.js) 0.20KB 0.18KB
types (crud.js) 0.20KB 0.18KB
types (data-display.js) 0.20KB 0.18KB
types (data-protocol.js) 0.20KB 0.19KB
types (data.js) 0.20KB 0.18KB
types (designer.js) 1.87KB 0.85KB
types (disclosure.js) 0.20KB 0.18KB
types (error-code.js) 1.54KB 0.88KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 0.20KB 0.18KB
types (form.js) 0.20KB 0.18KB
types (http-retry.js) 4.32KB 2.02KB
types (index.js) 2.71KB 1.34KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 2.59KB 1.31KB
types (navigation.js) 0.20KB 0.18KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 0.20KB 0.18KB
types (plugin-scope.js) 0.20KB 0.18KB
types (record-components.js) 0.20KB 0.19KB
types (record-semantics.js) 1.28KB 0.67KB
types (registry.js) 0.20KB 0.18KB
types (reports.js) 0.20KB 0.18KB
types (spec-report.js) 5.05KB 1.93KB
types (system-fields.js) 3.33KB 1.54KB
types (theme.js) 0.20KB 0.18KB
types (ui-action.js) 3.40KB 1.71KB
types (views.js) 0.20KB 0.18KB
types (widget.js) 0.20KB 0.18KB

Size Limits

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

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

Labels

documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

packages/runner/README.md §Development Workflow 教读者写 TypeScript schema 文件,但两个 loader 都只认 JSON

2 participants