Storybook 组件故事元数据(meta)默认导出全指南:Component Story Format 中的 default export 与 title/component 用法 Storybook 组件故事元数据meta默认导出全指南Component Story Format 中的 default export 与 title/component 用法【免费下载链接】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 FormatCSF中故事文件通过默认导出default export的meta对象来描述组件级元数据——它决定了组件如何出现在侧边栏、自动文档如何生成、addon 如何识别组件与参数。本文以仓库中的官方代码片段 button-story-default-export.md 为主体系统讲解meta中title与component两个核心字段的语义、自动标题的生成原理并给出 Angular、Svelte、Web Components、React、Vue、HTML 等全部渲染器的可运行写法。读完后你将能针对任意受支持的框架正确书写标准 CSF 3 与实验性 CSF Next 语法的默认导出。一、为什么需要默认导出meta 是故事的组件级配置一个 CSF 故事文件通常包含两类导出见 docs/writing-stories/index.mdx默认导出default export即meta描述这一个故事文件服务于哪个组件包括组件名称、所在层级以及会被 addon 使用的公共信息命名导出named exports描述组件的每一个具体状态也就是一个个 story。Storybook 依靠这份默认导出元数据来决定如何把你的故事列进侧边栏以及addon 需要哪些组件信息。例如下面这种最常见、最通用的形式适用于任意框架文件可为.js或.jsximport { Button } from ./Button; export default { /* title 属性是可选的。 * 省略后 Storybook 会依据文件路径自动生成标题auto-title。 */ title: Button, component: Button, };对应的 TypeScript 写法则会引入渲染器专属的Meta类型并用satisfies做类型收窄将鼠标悬停在meta上即可获得组件 props 级别的类型提示// Replace your-framework with the framework you are using, e.g. react-vite, nextjs, vue3-vite, etc. import type { Meta } from storybook/your-framework; import { Button } from ./Button; const meta { /* title 属性是可选的。 */ title: Button, component: Button, } satisfies Metatypeof Button; export default meta;二、核心字段剖析title 与 component2.1title控制侧边栏层级可选title决定该组件在侧边栏中的展示位置它是可选的。代码片段中每一份示例都保留了相同注释 The title prop is optional.当省略title时Storybook 从故事文件的物理位置推导标题即隐式implicit组织方式而当显式提供title时组件被固定放置在指定的层级位置explicit 方式。更完整的讨论见 naming-components-and-hierarchy.mdx其中页面正是直接引用了本文所依据的 button-story-default-export.md 作为命名故事的示范代码。另外值得注意自 Storybook 7.0 起故事标题是在构建期被静态分析的。默认导出必须包含一个可被静态读取的title属性或一个能据此计算出自动标题的component属性若要用id自定义故事 URL该id也必须静态可读依据 docs/writing-stories/index.mdx。2.2component把故事绑定到真实组件省略 title 时的自动标题来源component将故事文件与实际的组件类/函数关联起来是自动标题auto-title计算的数据来源。它在仓库侧边栏生成侧栏结构同时支撑 autodocs、Args 表、controls 等 addon 对组件 props 的解析。从实现上可以看得更清楚。autoTitle.ts 中userOrAutoTitleFromSpecifier的核心逻辑是当文件命中 stories glob 时如果存在用户提供的userTitle就优先使用它否则从文件路径中切出后缀连同titlePrefix一起清洗后拼成标题if (!userTitle) { const suffix normalizedFileName.replace(directory, ); let parts pathJoin([titlePrefix, suffix]).split(/); parts sanitize(parts); return parts.join(/); } if (!titlePrefix) { return userTitle; } return pathJoin([titlePrefix, userTitle]);其中sanitize负责去除.stories.js/.stories.ts之类的文件后缀并折叠atoms/button/button.stories.js中重复的目录段例如src/button/button.stories.js→button保证Button/Button.stories.js不会被渲染成Button/Button。这也解释了代码注释中省略 title 即自动生成标题的底层机制。三、type 层面的保证框架专属Meta类型在每个渲染器的public-types.ts中Meta都被定义成该渲染器 组件参数的组合类型例如 Reactcode/renderers/react/src/public-types.ts 中定义export type MetaTCmpOrArgs Args [TCmpOrArgs] extends [ComponentTypeany] ? ComponentAnnotationsReactRenderer, ComponentPropsTCmpOrArgs : ComponentAnnotationsReactRenderer, TCmpOrArgs;也就是说MetaButton会把组件 props 自动注入类型系统让你在写args、play时获得编译期校验。类似的类型定义同样存在于 Vue3code/renderers/vue3/src/public-types.ts、Web Componentscode/renderers/web-components/src/public-types.ts、HTMLcode/renderers/html/src/public-types.ts、Angularcode/frameworks/angular/src/client/public-types.ts等各渲染器实现中。在浏览器构建侧get-story-id.ts 会读取 story 文件路径优先取用户title否则调用上述自动标题逻辑得到autoTitle再由toId(autoTitle, storyName)生成稳定的 story id——title一旦变化故事的 URL id 也会随之变化。四、按框架逐一详解默认导出写法下面按渲染器组织完整覆盖官方片段给出的全部变体。同一渲染器内可能存在两种语法世代CSF 3稳定与标有 的CSF Next实验性。4.1 AngularAngular 的标准 CSF 3 使用storybook/angular提供的Meta类型并把组件类作为component传入import type { Meta } from storybook/angular; import { Button } from ./button.component; const meta: MetaButton { /* title 属性是可选的。省略后可从文件路径自动生成标题 */ title: Button, component: Button, }; export default meta;实验性的 CSF Next 语法则改为从.storybook/preview导入preview再调用preview.meta({ ... })构造同样的元数据对象该工厂方法会被后续语法继续统一使用见下方 React / Vue / Web Components 各小节import preview from ../.storybook/preview; import { Button } from ./button.component; const meta preview.meta({ /* title 属性是可选的。 */ title: Button, component: Button, });4.2 SvelteSvelte 用户有两种语法可写专用的Svelte CSFstorybook/addon-svelte-csf的defineMeta以及同样适用于 Svelte 的标准CSF 3。Svelte CSF.svelte故事文件写在script module中JavaScript 与 TypeScript 写法一致script module import { defineMeta } from storybook/addon-svelte-csf; import Button from ./Button.svelte; const { Story } defineMeta({ /* title 属性是可选的。 */ title: Button, component: Button, }); /scriptscript module import { defineMeta } from storybook/addon-svelte-csf; import Button from ./Button.svelte; const { Story } defineMeta({ /* title 属性是可选的。 */ title: Button, component: Button, }); /scriptSvelte 的标准 CSF 3JavaScript 使用对象字面量直接导出import Button from ./Button.svelte; export default { /* title 属性是可选的。 */ title: Button, component: Button, };TypeScript 版本则像 React 一样引入对应渲染器svelte-vite或sveltekit的Meta类型并配合satisfies// Replace your-framework with svelte-vite or sveltekit import type { Meta } from storybook/your-framework; import Button from ./Button.svelte; const meta { /* title 属性是可选的。 */ title: Button, component: Button, } satisfies Metatypeof Button; export default meta;4.3 HTMLHTML 渲染器没有组件类而是传入组件工厂函数createButton及其参数类型import { createButton } from ./Button; export default { /* title 属性是可选的。 */ title: Button, };注意HTML 的 JS 示例允许只写title而不写component——因为无框架环境下组件实例由渲染函数story 的render产生。TypeScript 版本把ButtonArgs作为Meta的类型参数传入import type { Meta } from storybook/html; import { createButton, ButtonArgs } from ./Button; const meta: MetaButtonArgs { /* title 属性是可选的。 */ title: Button, }; export default meta;4.4 Web ComponentsWeb Components 渲染器的特别之处在于component字段传入的是自定义元素标签名字符串如demo-button而不是类引用CSF 3JavaScriptexport default { title: Button, component: demo-button, };CSF 3TypeScriptMeta不携带类型参数import type { Meta } from storybook/web-components-vite; const meta: Meta { title: Button, component: demo-button, }; export default meta;CSF NextJavaScript 与 TypeScript 均通过preview.meta构造import preview from ../.storybook/preview; const meta preview.meta({ /* title 属性是可选的。 */ title: Button, component: demo-button, });import preview from ../.storybook/preview; const meta preview.meta({ /* title 属性是可选的。 */ title: Button, component: demo-button, });4.5 ReactReact 的稳定 CSF 3 写法即第二节中的通用形式satisfies Metatypeof Button。官方片段同时补充了 CSF Next 语法——从项目.storybook/preview中导入preview并调用preview.metaTypeScript 与 JavaScript 均如此import preview from ../.storybook/preview; import { Button } from ./Button; const meta preview.meta({ /* title 属性是可选的。 */ title: Button, component: Button, });import preview from ../.storybook/preview; import { Button } from ./Button; const meta preview.meta({ /* title 属性是可选的。 */ title: Button, component: Button, });4.6 Vue 3Vue 3 故事文件默认导入.vue单文件组件。CSF Next 语法同样基于preview.metaimport preview from ../.storybook/preview; import Button from ./Button.vue; const meta preview.meta({ /* title 属性是可选的。 */ title: Button, component: Button, });import preview from ../.storybook/preview; import Button from ./Button.vue; const meta preview.meta({ /* title 属性是可选的。 */ title: Button, component: Button, });五、CSF Next 语法速览preview.meta从哪来从上文可以看到凡是标注 CSF Next 的示例都把import preview from ../.storybook/preview作为第一步再以preview.meta({ ... })替代const meta { ... }。这一模式把全局 project annotations装饰器、参数与组件 meta通过preview实例统一起来是仓库中正在演进的下一代 CSF 编写入口关于其设计动机与完整说明可继续阅读 csf-next.mdx。由于它仍处于实验阶段跨大版本升级场景下应留意该语法与稳定版 CSF 3 的迁移关系。六、什么时候该省略 title自动标题与侧边栏组织建议官方片段中反复强调title是可选的因此实际工程中可按以下原则取舍组件文件与目录同名或按功能目录组织如src/atoms/Button/Button.stories.ts推荐省略title让侧边栏自动镜像目录结构。实现上autoTitle.ts 的sanitize会智能地去重与去后缀Button.stories→Button这正是官方注释指向的自动生成标题能力。需要固定层级/分组、或与目录结构解耦显式写title例如DesignSystem/Button用/表示层级可直接用于侧边栏分组与 button-story-grouped.md 所展示的目录式组织。无论哪种方式component都建议保留它是 addon如 Controls、Docs、a11y识别 props、生成自动文档的锚点。若你正在理解标题在索引与 URL 生成中的角色可顺着调用链阅读 get-story-id.ts它把解析得到的标题交给sanitize与toId最终拼出故事 id 与 kind即标题即结构这一设计在实现层的落点。七、结语一份正确的默认导出只需要记住两条黄金规则需要明确位置就给title不给就让 Storybook 依据文件路径自动推导始终把真实的component关联上为类型安全与 addon 能力提供基础。无论是 Angular、Svelte、Vue、Web Components、HTML 还是 React本文给出的各渲染器变体都可直接复制进你的Button.stories.*文件运行。原始多语言对照版本保存在 docs/_snippets/button-story-default-export.md其中每种渲染器的差异点也正是本节对照表所梳理的内容可作为团队规范落地时的唯一参考源。【免费下载链接】storybookStorybook is the industry standard workshop for building, documenting, and testing UI components in isolation项目地址: https://gitcode.com/GitHub_Trending/st/storybook创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考