Skip to content

docs(components): README §Setup 删掉 Tailwind 3 的 config 步骤,并修正预构建样式表的 specifier (#3780) - #3886

Merged
yinlianghui merged 1 commit into
mainfrom
claude/issue-3780-components-readme-tailwind
Aug 9, 2026
Merged

docs(components): README §Setup 删掉 Tailwind 3 的 config 步骤,并修正预构建样式表的 specifier (#3780)#3886
yinlianghui merged 1 commit into
mainfrom
claude/issue-3780-components-readme-tailwind

Conversation

@yinlianghui

Copy link
Copy Markdown
Collaborator

Fixes #3780

packages/components/README.md §Setup 第 1 步教读者写一个带 content 数组的 tailwind.config.js。该包是 Tailwind 4:它自己没有这个文件,postcss.config.js 加载 @tailwindcss/postcss,src/index.css 首行 @import 'tailwindcss' 并使用 @theme / @custom-variant / @source。Tailwind 4 不经 CSS 里的 @config opt-in 不会加载 config 文件,所以照第 1 步做的读者写出的是一个没人读的文件。#3750 已把两行之上的 peer 行从 ^3.0.0 收窄到 ^4.2.1,底下这段散文没跟上。

分支自 origin/main = 56ff0916e09085a5430957d5c62a7e5dc1a80d82 显式 sha 切出。

先量再选:这一步不能翻译,只能删

issue 留了一格未定:第 1 步在 v4 下改写成 @source,还是整步删除。按分诊「先量再选」,对着真实安装测量而不是照着 v4 语法逐句翻译 —— 结论是这一步的前提在 Tailwind 4 下不可达,不只是拼错了。

消费者形状的 fixture(node_modules 里装着本包,Tailwind 4.3.3 + @tailwindcss/postcss),四组 CSS 入口各跑一次真实编译。方向在跑之前先写进探针脚本头部,以便被证伪:

消费者入口 消费者自己的 class 库的形状类 utility 库的主题类 utility
第 1 步原样(v3 config,无 @config)
v4 @source 指向已安装包
第 1 步 + 显式 @config opt-in
第 2 步的预构建样式表 不归它管
  • 第 1 步原样是完全空转的:整份产物 74 条选择器,全部来自消费者自己的源码,库的 utility 一条都没有 —— issue 的前提实测坐实。
  • 两种「忠实翻译」都到不了第 1 步想去的地方:bg-primary / bg-background / border-input / ring-ring(整套 Shadcn 配色)只在声明其 token 的 @theme 块被编译处存在,而该块在 packages/components/src/index.css —— files 只发布 dist,不发布它。扫描已发布文件只能把形状类 utility(inline-flex / rounded-md / h-9)再生成一遍,永远补不回主题类。

所以「改写为 @source」会是一条新的错指令:读者会得到一堆没有配色的组件,然后去排查一个不存在的路径问题。该步整步删除,替换它的段落明写读者接下来最可能伸手去拿的 @source 行为什么也不是答案。

预构建样式表覆盖多少,也是量出来的

dist/index.js + dist/index.umd.cjs 里所有 class 形状的 token 取出来(18099 个;这就是一个 node_modules glob 所能看到的全部表面),对着本包自己的主题编译,再与发布的 dist/index.css 逐选择器比对:

harvested 18099 distinct tokens from dist/index.js + dist/index.umd.cjs
shipped dist/index.css : 161.98 kB, 1410 rules
node_modules-scan probe: 152.78 kB, 1331 rules
rules the probe produces that the shipped CSS does NOT contain: 0

零缺失 —— 预构建 CSS 是扫描所能得到之物的严格超集

顺带修正:存活下来的 import 步骤 specifier 是错的

测量过程中发现第 2 步自己也不成立。它写 @object-ui/components/dist/style.css,而 manifest 的 exports 映射里没有这个子路径:

OK   @object-ui/components/style.css      -> …/packages/components/dist/index.css
FAIL @object-ui/components/dist/style.css -> ERR_PACKAGE_PATH_NOT_EXPORTED
FAIL @object-ui/components/dist/index.css -> ERR_PACKAGE_PATH_NOT_EXPORTED

而且 dist/style.css 这个文件根本不存在(构建产物是 dist/index.css)。导出的拼法是 @object-ui/components/style.css —— 三个包的 demo(plugin-gantt / plugin-grid 两处)、content/docs/guide/quick-start.md:57,以及 packages/components/src/index.ts:14 里那句把读者指向本 README 的注释,一直用的都是它;只有 README 自己是错的。

这一条同 PR 修而不是另立,理由是它与本 issue 的裁决直接耦合:删掉第 1 步之后,第 2 步是 §Setup 里唯一剩下的样式指令,把一条 ERR_PACKAGE_PATH_NOT_EXPORTED 的 specifier 留成唯一答案,比原来两步都错更糟。

改后的 §Setup 是跑通过的

PR 里写给读者的那两行,按同一套 fixture 实测(180.27 kB,1447 条选择器):形状类、主题类、以及消费者自己源码里的 class 全部present。作为对照,content/docs/guide/quick-start.md 现行教法(同样两行再加一条 @source node_modules)是 280.25 kB / 1461 条 —— 多 100 kB,换来 14 条没人用的选择器(已另立 #3884)。

反向验证

doc 类改动没有可回装的谓词,可测等价物取三样,方向均在跑之前写定:

  1. 把删掉的那一步当作被测对象跑一遍(而不是回装进代码):v3 config 原样放进真实 Tailwind 4 编译 —— 预测「库 utility 全无」,实测 74 条选择器里库的 utility 零命中。这一步的空转是被运行出来的,不是从 v4 文档推出来的。
  2. 门禁前后全绿:check-doc-links.mjscheck-control-bytes.mjsdoc-version-claims.test.ts(14 passed —— peer 行区块未动,restatement 断言仍在读同一行对同一 manifest)、check-changeset-presence.mjscheck-changeset-no-major.mjscheck-changeset-fixed.mjs、全仓 turbo run type-check(78/78)。
  3. 我教给读者的每条写法自己跑一遍:见上一节。

doc-version-claims 的 inventory 无需联动:本次改动不新增版本字面量(新增散文只写不带点、不带运算符的 Tailwind 4,该拼法被 VERSION 正则明确排除,test 自己的注释就记着这件事),peer 行区块一个字节没动。

changeset

check-changeset-presence.mjs 判定不欠(它只守每个包的 src/**,README 在其守备面之外,header 里明写了这条边界)。仍按 #3749/PR3860 先例补一份空 frontmatter 的 changeset:不声明包,因为没有任何已发布产物改变形状、没有版本字面量移动,改好的 README 随该版本组的下一次发版一起出去。

越界发现(均已查重后另立,本 PR 不碰)


Generated by Claude Code

…specifier (#3780)

§Setup 第 1 步教读者写一个带 content 数组的 tailwind.config.js。该包是
Tailwind 4:它自己没有这个文件,postcss.config.js 加载
@tailwindcss/postcss,src/index.css 首行 @import 'tailwindcss' 且用
@theme / @custom-variant / @source。Tailwind 4 不经 CSS 里的 @config
opt-in 不会加载 config 文件,所以照做的读者写出的是一个没人读的文件。
#3750 已把两行之上的 peer 行从 ^3.0.0 收窄到 ^4.2.1,底下这段散文没跟上。

先量再改,因为这一步的前提在 Tailwind 4 下是不可达而非拼错。对着真实安装
跑了四组消费者形状的 CSS 入口(Tailwind 4.3.3 + @tailwindcss/postcss,每组
一次真实编译):第 1 步原样 = 库的 utility 一条都没有;改写成 v4 的 @source
或补上显式 @config = 形状类 utility 回来了,主题类仍然全无。bg-primary /
bg-background / border-input / ring-ring 只在声明其 token 的 @theme 块被
编译处存在,而该块在 src/index.css —— files 不发布它。所以「把第 1 步翻译成
@source」会是一条新的错指令,不是修好的旧指令:该步整步删除,替换它的段落
说清读者接下来最可能伸手去拿的 @source 行为什么也不是答案。

预构建样式表覆盖多少同样是量出来的:dist/index.js + dist/index.umd.cjs 里
所有 class 形状的 token(一个 node_modules glob 所能看到的全部表面)对着本包
自己的主题编译,产出 1331 条规则,全部已在发布的 dist/index.css 的 1410 条
之内 —— 零缺失。预构建 CSS 是扫描所能得到之物的严格超集。

存活下来的 import 步骤 specifier 也是错的:它写 dist/style.css,而 exports
映射里没有这个子路径(Node 报 ERR_PACKAGE_PATH_NOT_EXPORTED),该文件也不
存在(构建产物是 dist/index.css)。导出的拼法是 @object-ui/components/style.css
—— 三个包的 demo、content/docs/guide/quick-start.md 以及 src/index.ts 里那句
把读者指向本 README 的注释,一直用的都是它。

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GTRjn8xBqp75dk7kFupVRt
@vercel

vercel Bot commented Aug 8, 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 8, 2026 11:54pm

Request Review

@github-actions github-actions Bot added documentation Improvements or additions to documentation package: components labels Aug 8, 2026
@github-actions

github-actions Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Main entry (gzip) 28.1 KB 350 KB
Entry file index-D8DbRrMg.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) 482.39KB 106.34KB
core (index.js) 2.96KB 1.13KB
create-plugin (index.js) 10.08KB 3.26KB
data-objectstack (index.js) 139.61KB 35.99KB
fields (index.js) 230.82KB 56.70KB
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) 27.59KB 6.63KB
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.33KB 42.79KB
plugin-dashboard (index.js) 117.21KB 30.27KB
plugin-designer (index.js) 210.51KB 42.51KB
plugin-detail (index.js) 236.17KB 58.82KB
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) 187.63KB 49.66KB
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

Copy link
Copy Markdown
Collaborator Author

✅ 验收(PM,session session_01GTRjn8xBqp75dk7kFupVRt)

实物核验:头 de3ff7f06,2 文件(README + changeset 空 frontmatter);README diff 全读 —— v3 config 步骤删除、幸存步骤 specifier 修正为 exports 真实存在的 @object-ui/components/style.css、反 @source 的主题类机理写进 README 正文防读者按直觉加回;trailer 0;与在飞零相交。
CI 终态(独立复核):19 检查全部 completed(Bundle Analysis 最后落绿),零失败。

裁定要点:

  • 「先量再选」执行到位且测量证伪了隐含第三选项:四组入口探针证明 v3 config 完全空转、@source/@config 只能补形状类补不回主题类(@theme 块在未发布 src)、预构建 CSS 是严格超集(0 缺失)—— 改写为 @source 会是一条新错指令,删除是唯一对的方向。
  • 越界 specifier 修正采纳:删第 1 步后 dist/style.css(ERR_PACKAGE_PATH_NOT_EXPORTED,文件不存在)会成为唯一幸存的样式指令 —— 同节强耦合、证据充分(exports 映射 + 包内三处既有正确用法),同 PR 修是对的。
  • 教读者的两行自己按消费者 fixture 实测跑通(180.27 kB / 1447 条,形状+主题+消费者自有 class 全有)。
  • doc-version-claims 无需联动的判定有依据(peer 区块零字节动、Tailwind 4 拼法被 VERSION 正则排除且有测试注释背书)。

转 ready 并挂 auto-merge。越界 #3883(theming/troubleshooting 同根因两文件)、#3884(quick-start @source 冗余 +100kB 且解释误导排查方向)归分诊席。


Generated by Claude Code

@yinlianghui
yinlianghui marked this pull request as ready for review August 9, 2026 00:04
@yinlianghui
yinlianghui added this pull request to the merge queue Aug 9, 2026
Merged via the queue into main with commit 116e5ea Aug 9, 2026
20 checks passed
@yinlianghui
yinlianghui deleted the claude/issue-3780-components-readme-tailwind branch August 9, 2026 00:05
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 package: components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

components README §Setup 第 1 步仍是 Tailwind 3 写法(叫读者写 tailwind.config.js),而该包是 v4 CSS-first、全仓没有这个文件

2 participants