Storybook CSF 3.0 标题体系详解:meta.title、component 自动标题与 story.name 的命名规则
2026/9/8 21:38:19 网站建设 项目流程

Storybook CSF 3.0 标题体系详解:meta.title、component 自动标题与 story.name 的命名规则

【免费下载链接】storybookStorybook is the industry standard workshop for building, documenting, and testing UI components in isolation项目地址: https://gitcode.com/GitHub_Trending/st/storybook

这篇技术指南聚焦 Storybook Component Story Format 3.0(CSF 3.0)中的"标题(title)与命名"控制机制,内容以仓库中面向组件命名示例的代码片段文档为主体,并结合其出处——Sidebar & URLS 配置文档中的 "CSF 3.0 auto-titles" 章节展开。读完本文,你将掌握如何在 CSF 文件中通过titlecomponentname精确控制组件与单个 Story 在侧边栏层级与 URL 中的呈现,理解 Storybook 自动推导标题(auto-title)的完整规则,并能在 JS/TS/MDX 三种场景中正确写出可运行的标题配置。

一、标题机制一览:title、component 与 name 三者各自负责什么

在 CSF 3.0 中,每个.stories文件通过meta(默认导出)描述组件容器,通过命名导出对象描述单个 Story。决定"这个组件/这条 Story 在 Storybook 里叫什么、出现在侧边栏哪个位置"的核心字段有三个:

字段作用层级用途
titlemeta(文件级)设置 Story 容器在侧边栏中的完整路径名,含/时会产生分组层级,例如components/Button
componentmeta(文件级)关联被测组件;当未设置title时,Storybook 会根据文件物理路径自动推断标题
name单个 Story覆盖该 Story 的显示名称;不设置时默认使用导出变量名

三者可同时使用并相互配合,这也是示例文档要表达的核心:自动标题(auto-title)与显式标题选项完全兼容,设置title后你依然可以使用显式的name逐条命名 Story。

二、CSF 3.0 meta 的标准写法:JS 与 TS 双版本

以按钮组件为例,示例文档给出了.js/.jsx.ts/.tsx两种等价写法。

JS/JSX 版本(对应 src/components/Button/Button.stories.js):

import { Button } from './Button'; export default { // Sets the name for the stories container title: 'components/Button', // The component name will be used if `title` is not set component: Button, }; // The story variable name will be used if `name` is not set const Primary = { // Sets the name for that particular story name: 'Primary', args: { label: 'Button', }, };

TypeScript 版本使用satisfies Meta<typeof Button>做类型收窄,让框架在编译期帮你校验 title/component/args 等字段拼写:

// Replace your-framework with the framework you are using, e.g. react-vite, nextjs, vue3-vite, etc. import type { Meta, StoryObj } from '@storybook/your-framework'; import { Button } from './Button'; const meta = { // Sets the name for the stories container title: 'components/Button', // The component name will be used if `title` is not set component: Button, } satisfies Meta<typeof Button>; export default meta; type Story = StoryObj<typeof meta>; // The story variable name will be used if `name` is not set const Primary: Story = { // Sets the name for that particular story name: 'Primary', args: { label: 'Button', }, };

两点实践提醒(对应示例中的注释):

  • 类型导入处的@storybook/your-framework是占位符,应按实际框架替换,例如@storybook/react-vite@storybook/nextjs@storybook/vue3-vite等。
  • title是可选的:一旦省略,Storybook 会根据文件所在位置自动推断标题,而component字段仍用于类型推断与文档生成,因此建议始终显式写出。

注意:示例中的对象式Primary是尚未作为命名导出列出的写法;若想让 Story 出现在侧边栏,仍需通过export const Primary = { ... }之类的方式导出(CSF 3.0 中常见的是把对象拆出来,再export const X = { ...Primary })。从仓库中的 CSF 解析实现看,meta 中title的取值会被用于生成稳定 storyId 与 URL 中的kind,这正是 title 命名在全局唯一的根因,详见 get-story-id.ts。

三、title 的斜杠语法:如何构建侧边栏分组层级

示例把 title 写作components/Button,其中/是侧边栏的分组分隔符。Storybook 会按共同前缀把带斜杠的 title 归组:所有components/...标题下的组件会收进一个名为components的分组(文件夹),Button成为该分组下的叶子节点。

Sidebar & URLS 文档给出了两条实操建议:

  • 顶层节点默认被渲染为 "Roots"(侧边栏的"区段"),更低层分组显示为文件夹;如想将顶层节点也折叠成文件夹,可在./storybook/manager.js中将sidebar.showRoots设为false
  • 推荐的层级命名尽量镜像组件文件的文件系统路径:例如组件在components/modals/Alert.js,那么 Stories 文件命名为components/modals/Alert.stories.js,title 写为Components/Modals/Alert,让目录结构、文件名与侧边栏结构一一对应,便于长期维护。

四、省略 title:Storybook 的自动标题(auto-title)规则

自 Storybook 6.4 引入 CSF 3.0(实验性)起,你可以省略 meta 中的title,让 Storybook 依据故事文件的物理位置自动推断标题,这正是示例文档出现的上下文。自动标题与titlename等显式配置可以并存、按需混用。

自动标题的推断逻辑实现在 autoTitle.ts 中,核心函数userOrAutoTitleFromSpecifier的优先级是:匹配到 stories 配置项后,若存在用户显式title,优先用用户 title;仅在缺失时才由文件路径推导。该文件还实现了若干重要启发式规则,可由对应测试 autoTitle.test.ts 印证:

  1. 保留大小写(Storybook 6.5 起):不再依赖 LodashstartCase转换,components/MyComponent文件会得到components/MyComponent(而不是被拆词成My Component),文件名大小写被原样保留。
  2. 去除冗余文件名:当文件名与父目录同名(如MyComponent/MyComponent.stories.ts),或文件名为index.stories.ts时,重复段会被剔除——按旧行为Components/MyComponent/MyComponent会简化为Components/MyComponent。相关示例见 storybook-csf-3-auto-title-redundant.md。若需要保留旧命名,只需显式给 meta 添加title
  3. 剥离后缀与扩展名:推导时会去掉.story(s)、文件扩展名以及路径中的分隔冗余(sanitize函数与pathJoin实现)。
  4. titlePrefix 自动前缀:若在 stories 配置对象中配置了titlePrefix,所有匹配故事(无论自动还是显式 title)都会加上此前缀;测试中的快照如atoms/titleatoms/...直接证明了显式 title 与前缀的拼接行为。

需要说明的是,自动标题会保留文件系统路径的层级作为侧边栏层级。例如当你的.storybook/main.tsstories: ['../src/**/*.stories.@(js|jsx|mjs|ts|tsx)']加载 stories 且文件位于src/components/Button.stories.tsx时,该组件在侧边栏会自动显示为components/Button(示例文档语境下的components/My Component情形同理)。

五、story 的 name 与导出变量名:谁决定显示名

示例中PrimaryStory 同时设置了export const变量名与name: 'Primary'。二者的分工在 Sidebar & URLS 文档中被明确表述:

Storybook will prioritize theidover the title for ID generation if provided and prioritize thestory.nameover the export key for display.

即:侧边栏与 Docs 中的显示名以story.name为准,未设置时才退化为导出变量名。因此当你要把导出变量名留作代码内引用、却想让读者看到更友好的标题时(例如含空格、中文或长描述),就给 Story 设置name。相应地,story 显示名的修改会自动参与 URL 与 permalink 的生成。

六、从 title 到 URL:storyId 的生成规则

title 不只影响观感,还会决定每个 Story 的稳定 ID 与可分享 URL。默认规则是:Storybook 依据"组件 title + 故事名"生成 ID;例如 title 为foo/bar、导出名为baz的故事会得到 IDfoo-bar--baz,对应链接形如?path=/story/foo-bar--baz(见 Sidebar & URLS 文档)。

若需要在不破坏既有 permalink 的前提下调整层级或显示名,可手动为 meta/Story 提供稳定的idid优先级高于 title),这在发布型 Storybook 中尤其重要。整体调用链在仓库中可见于 get-story-id.ts:先通过getStoryTitle拿到(自动或用户)title,再由storyNameFromExport归一化故事名,最终toId(autoTitle, storyName)产出 storyId,title 经sanitize归一化为 URL 友好的kind

七、MDX 文档页里的 Meta/Story:文档页标题与组件页引用

.mdx文档文件中,同样使用标题体系组织页面。示例文档给出了Button.mdx的用法(注意其中的 import 写法为示例使用方式,来自 '@storybook/addon-docs/blocks'):

import { Meta, Story } from '@storybook/addon-docs/blocks'; {/* 👇 Documentation-only page */} <Meta title="Documentation" /> {/* 👇 Component documentation page */} import * as ButtonStories from './Button.stories'; <Meta of={ButtonStories} /> <Story of={ButtonStories.Primary} />

该示例同时展示三种常见形态:

  • 纯文档页(documentation-only page):通过<Meta title="Documentation" />显式命名一个不含组件渲染的文档页面,title 决定其在侧边栏中的层级归属。
  • 组件文档页<Meta of={ButtonStories} />引用同目录下Button.stories模块的全部导出,让该 MDX 页与 CSF 中定义的组件及标题自动关联。
  • 渲染指定故事<Story of={ButtonStories.Primary} />基于of语法按引用渲染Primary这条 Story,无需手动复制 args 配置。

由此可以总结出贯穿 JS/TS/MDX 的统一心智模型:CSF 文件是"单一事实来源",title/自动标题决定容器归属,name/导出名决定故事显示名,Meta/Storyof引用则让文档页复用这套命名体系,从而保持侧边栏、URL、文档三处命名一致。

八、小结:何时显式 title,何时交给自动标题

  • 侧边栏需要精确层级、需按业务模块而非目录组织、或目录路径与展示名不一致时,在 meta 中显式声明title(配合/分隔),这是最可控的方案;
  • 目录结构合理、希望"移动文件即自动重命名"时,省略title,依赖文件路径自动推断,并用titlePrefix统一打前缀;
  • 无论哪种方案,都可以给单条 Story 设置name控制显示名,并牢记只有显式title缺失时自动推断才会生效,component字段与命名无关却对类型安全与文档自动生成至关重要。

上述所有规则,均可回到仓库中的示例片段、侧边栏配置文档以及 autoTitle.ts、get-story-id.ts 及其测试处进一步验证,是理解 Storybook 命名与路由体系的可靠参考入口。

【免费下载链接】storybookStorybook is the industry standard workshop for building, documenting, and testing UI components in isolation项目地址: https://gitcode.com/GitHub_Trending/st/storybook

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询