自动文档和 Storybook
观看视频教程
Storybook Autodocs 是一个强大的工具,可以帮助您快速为 UI 组件生成全面的文档。 通过利用 Autodocs,您可以将您的 stories 转换为实时文档,并通过 MDX 和 Doc Blocks 进一步扩展,从而清晰简洁地了解组件的功能。
Storybook 推断相关的元数据 (例如,args
, argTypes
, parameters
),并自动生成一个文档页面,其中包含此信息,并将其放置在侧边栏中组件树的根级别。
设置自动文档
Autodocs 通过 tags 配置。 如果 CSF 文件包含至少一个标记为 autodocs
的 story,则会为该组件生成一个文档页面。
要为项目中的所有 stories 启用自动文档,请将其添加到您的 tags
中的 .storybook/preview.js|ts
文件中
// Replace your-renderer with the renderer you are using (e.g., react, vue3)
import type { Preview } from '@storybook/your-renderer';
const preview: Preview = {
// ...rest of preview
//👇 Enables auto-generated documentation for all stories
tags: ['autodocs'],
};
export default preview;
您也可以在组件(或 story)级别启用它
// Replace your-framework with the framework you are using (e.g., nextjs, vue3-vite)
import type { Meta } from '@storybook/your-framework';
import { Button } from './Button';
const meta: Meta<typeof Button> = {
component: Button,
//👇 Enables auto-generated documentation for this component and includes all stories in this file
tags: ['autodocs'],
};
export default meta;
您可以通过删除 tag 来禁用特定组件的自动文档
// Replace your-framework with the framework you are using (e.g., nextjs, vue3-vite)
import type { Meta } from '@storybook/your-framework';
import { Page } from './Page';
const meta: Meta<typeof Page> = {
component: Page,
// 👇 Disable auto-generated documentation for this component
tags: ['!autodocs'],
};
export default meta;
同样,您可以通过删除 tag 从自动文档页面中排除特定的 story
// Replace your-framework with the framework you are using (e.g., nextjs, vue3-vite)
import type { Meta, StoryObj } from '@storybook/your-framework';
import { Button } from './Button';
const meta: Meta<typeof Button> = {
component: Button,
//👇 Enables auto-generated documentation for this component and includes all stories in this file
tags: ['autodocs'],
};
export default meta;
type Story = StoryObj<typeof Button>;
export const UndocumentedStory: Story = {
// 👇 Removes this story from auto-generated documentation
tags: ['!autodocs'],
};
配置
除了使用 tags
启用该功能外,您还可以扩展您的 Storybook 配置文件(即 .storybook/main.js|ts|cjs
)并提供其他选项来控制文档的创建方式。 下面列出了可用的选项以及如何使用它们的示例。
// Replace your-framework with the framework you are using (e.g., react-webpack5, vue3-vite)
import type { StorybookConfig } from '@storybook/your-framework';
const config: StorybookConfig = {
framework: '@storybook/your-framework',
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
addons: ['@storybook/addon-essentials'],
docs: {
//👇 See the table below for the list of supported options
defaultName: 'Documentation',
},
};
export default config;
选项 | 描述 |
---|---|
defaultName | 重命名自动生成的文档页面 默认值: docs: { defaultName: '文档' } |
编写自定义模板
观看视频教程
要替换 Storybook 使用的默认文档模板,您可以扩展您的 UI 配置文件(即 .storybook/preview.js|ts
)并引入 docs
参数。 此参数接受一个 page
函数,该函数返回一个 React 组件,您可以使用该组件生成所需的模板。 例如
// Replace your-framework with the framework you are using (e.g., react, vue3)
import { Preview } from '@storybook/your-framework';
import { Title, Subtitle, Description, Primary, Controls, Stories } from '@storybook/blocks';
const preview: Preview = {
parameters: {
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
docs: {
page: () => (
<>
<Title />
<Subtitle />
<Description />
<Primary />
<Controls />
<Stories />
</>
),
},
},
};
export default preview;
在内部,Storybook 使用类似的实现来生成默认模板。 请参阅 Doc Blocks API 参考,以了解有关 Doc Blocks 工作原理的更多信息。
更详细地了解代码片段。 当 Storybook 启动时,它将使用以下组成的自定义模板覆盖默认模板
- 一个标头,其中包含由
Title
、Subtitle
和Description
Doc Blocks 检索的组件元数据。 - 文件中通过
Primary
Doc Block 定义的第一个 story,带有一组方便的 UI 控件,用于放大和缩小组件。 - 一个交互式表格,其中包含通过
Controls
Doc Block 在 story 中定义的所有相关args
和argTypes
。 - 通过
Stories
Doc Block 概述其余的 stories。
使用 MDX
您还可以使用 MDX 生成文档模板。 这在未配置 JSX 处理的非 React 项目中非常有用。 通常,当您在项目中创建 MDX 文件时,它被视为普通文档。 要指示 MDX 文件是文档模板,请将 isTemplate
属性提供给其 Meta
Doc Block。 例如
import { Meta, Title, Primary, Controls, Stories } from '@storybook/blocks';
{/*
* 👇 The isTemplate property is required to tell Storybook that this is a template
* See https://storybook.org.cn/docs/api/doc-blocks/doc-block-meta
* to learn how to use
*/}
<Meta isTemplate />
<Title />
# Default implementation
<Primary />
## Inputs
The component accepts the following inputs (props):
<Controls />
---
## Additional variations
Listed below are additional variations of the component.
<Stories />
然后,您可以通过导入它在您的 .storybook/preview.js|ts
或单个 story 文件中使用它
import DocumentationTemplate from './DocumentationTemplate.mdx';
export default {
parameters: {
docs: {
page: DocumentationTemplate,
},
},
};
如果您只需要覆盖单个组件的文档页面,我们建议创建一个 MDX 文件,并通过 <Meta of={} />
Doc Block 直接引用它。
生成目录
Storybook 的自动生成的文档页面可能很长且难以导航。 为了帮助解决这个问题,您可以启用目录功能,以提供文档页面的快速概览,并允许用户跳转到特定部分。 要启用它,请扩展您的 Storybook UI 配置文件(即 .storybook/preview.js|ts
)并提供带有 toc
属性的 docs
参数。
// Replace your-framework with the framework you are using (e.g., react, vue3)
import { Preview } from '@storybook/your-framework';
const preview: Preview = {
parameters: {
docs: {
toc: true, // 👈 Enables the table of contents
},
},
};
export default preview;
配置目录
默认情况下,文档页面上的目录将仅显示自动生成的 h3
标题。 但是,如果您想自定义目录,可以向 toc
属性添加更多参数。 以下是可用的选项以及如何使用它们的示例。
选项 | 描述 |
---|---|
contentsSelector | 定义容器的 CSS 选择器以搜索标题toc: { contentsSelector: '.sbdocs-content' } |
disable | 隐藏文档页面的目录toc: { disable: true } |
headingSelector | 定义要在目录中显示的标题列表toc: { headingSelector: 'h1, h2, h3' } |
ignoreSelector | 配置目录以忽略特定的标题或 stories。 默认情况下,目录将忽略放置在 Story blocks 中的所有内容toc: { ignoreSelector: '.docs-story h2' } |
title | 定义目录的标题。 接受以下之一: string , null , React 元素toc: { title: '目录' } |
unsafeTocbotOptions | 提供额外的 TocBot 配置选项toc: { unsafeTocbotOptions: { orderedList: true } } |
contentsSelector
, headingSelector
, 和 ignoreSelector
属性允许进行额外的自定义。 有关使用它们的更多信息,请参阅 Tocbot
文档。
// Replace your-framework with the framework you are using (e.g., react, vue3)
import { Preview } from '@storybook/your-framework';
const preview: Preview = {
parameters: {
docs: {
toc: {
contentsSelector: '.sbdocs-content',
headingSelector: 'h1, h2, h3',
ignoreSelector: '#primary',
title: 'Table of Contents',
disable: false,
unsafeTocbotOptions: {
orderedList: false,
},
},
},
},
};
export default preview;
组件级配置
如果您想为特定的 Story 自定义目录,可以在 Story 的默认导出中包含 toc
属性,并提供所需的配置。例如,如果您需要隐藏特定 Story 的目录,请按照如下方式调整您的 Story:
// Replace your-framework with the name of your framework
import type { Meta } from '@storybook/your-framework';
import { MyComponent } from './MyComponent';
const meta: Meta<typeof MyComponent> = {
component: MyComponent,
tags: ['autodocs'],
parameters: {
docs: {
toc: {
disable: true, // 👈 Disables the table of contents
},
},
},
};
export default meta;
自定义组件文档
使用 Storybook 的 Autodocs 创建自动化文档为您构建可持续的文档模式提供了起点。然而,它可能并不适用于所有情况,您可能希望对其进行扩展并提供其他信息。我们建议结合 MDX 和 Storybook 的 Doc Blocks 来编写您的文档。
高级配置
为多个组件编写文档
有时,将多个组件一起编写文档会很有帮助。例如,组件库的 ButtonGroup 和 Button 组件如果缺少其中一个,可能就失去了意义。
Autodocs 允许您为您通过 component
属性定义的“主要”组件以及与其相关的一个或多个 subcomponents
编写文档。
import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import { List } from './List';
import { ListItem } from './ListItem';
const meta: Meta<typeof List> = {
component: List,
subcomponents: { ListItem }, //👈 Adds the ListItem component as a subcomponent
};
export default meta;
type Story = StoryObj<typeof List>;
export const Empty: Story = {};
export const OneItem: Story = {
render: (args) => (
<List {...args}>
<ListItem />
</List>
),
};
主要组件及其子组件将以选项卡形式显示在 ArgTypes
doc block 中。选项卡标题将与 subcomponents
对象的键相对应。
如果您想以不同的方式组织组件组的文档,我们建议使用 MDX。它可以让您完全控制组件的显示方式,并支持任何配置。
自定义 Docs Container
Docs Container 是包装文档页面的组件。它负责在 Storybook 的 UI 中渲染文档页面。您可以通过创建自己的组件并更新您的 Storybook UI 配置文件(即 .storybook/preview.js|ts
)来引用它,从而对其进行自定义。
import * as React from 'react';
// Replace your-framework with the framework you are using (e.g., react, vue3)
import { Preview } from '@storybook/your-framework';
import { DocsContainer } from '@storybook/blocks';
const ExampleContainer = ({ children, ...props }) => {
return <DocsContainer {...props}>{children}</DocsContainer>;
};
const preview: Preview = {
parameters: {
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
docs: {
container: ExampleContainer,
},
},
};
export default preview;
覆盖默认主题
默认情况下,Storybook 为 UI 提供了两个主题:light
和 dark
。如果您需要自定义文档使用的主题以匹配现有主题,您可以更新您的 Storybook UI 配置文件(即 .storybook/preview.js|ts
)并应用它。
// Replace your-framework with the framework you are using (e.g., react, vue3)
import { Preview } from '@storybook/your-framework';
import { themes, ensure } from '@storybook/theming';
const preview: Preview = {
parameters: {
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
docs: {
theme: ensure(themes.dark), // The replacement theme to use
},
},
};
export default preview;
使用自定义 MDX 组件
开箱即用,Storybook 拥有一组组件,您可以使用它们来自定义您的文档页面。如果您正在使用设计系统或组件库,并希望将它们添加到您的文档页面,您可以覆盖从 @mdx-js/react
继承的 MDXProvider
组件,使用您自己的组件。但是,这里有一个注意事项,组件替换仅在您使用 Markdown 语法(例如,#
用于标题)编写文档时才会生效。原生 HTML 元素,例如 <h1>
,将不会被您的自定义实现替换。
// Replace your-framework with the framework you are using (e.g., react, vue3)
import { Preview } from '@storybook/your-framework';
import { MDXProvider } from '@mdx-js/react';
import { DocsContainer } from '@storybook/blocks';
import * as DesignSystem from 'your-design-system';
export const MyDocsContainer = (props) => (
<MDXProvider
components={{
h1: DesignSystem.H1,
h2: DesignSystem.H2,
}}
>
<DocsContainer {...props} />
</MDXProvider>
);
const preview: Preview = {
parameters: {
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
docs: {
container: MyDocsContainer,
},
},
};
export default preview;
这不是 Storybook 的问题,而是 MDX 工作方式的细节。来自他们的迁移指南
“我们现在‘沙箱化’组件,因为找不到更好的名字。这意味着当您为 h1 传递组件时,它确实用于 # hi
,但不用于 <h1>hi</h1>
”
问题排查
目录未按预期渲染
当使用 Autodocs 的目录时,您可能会遇到目录显示效果与预期不同的情况。为了帮助您解决这些问题,我们整理了一系列可能导致问题的场景。
对于简单的文档页面
如果您的文档页面只有一个匹配的标题并为其创建了目录,则默认情况下目录不会被隐藏。此问题的一个潜在解决方案是添加第二个标题或完全关闭目录。
对于小屏幕
如果屏幕宽度小于 1200px,则默认情况下目录将被隐藏。目前,对于此问题没有内置的解决方案,并且不影响文档页面的样式兼容性。
使用 MDX
如果您正在使用 MDX 编写未附加的文档,则主要由于当前实现不支持基于当前实现定义参数,因此您无法自定义目录。因此,目录将始终恢复为全局提供的默认配置。
自动生成的文档未在 monorepo 设置中显示
开箱即用,Storybook 的 Autodocs 功能旨在自动为您的 Story 生成文档。然而,如果您正在使用 monorepo 设置(例如 Yarn Workspaces
, pnpm Workspaces
),您可能会遇到部分文档未为您生成的问题。为了帮助您排查这些问题,我们准备了一些可能对您有所帮助的建议。
更新您的导入语句以直接引用组件,而不是包的根目录。例如
// Replace your-framework with the name of your framework
import type { Meta } from '@storybook/your-framework';
// ❌ Don't use the package's index file to import the component.
// import { MyComponent } from '@component-package';
// ✅ Use the component's export to import it directly.
import { MyComponent } from '@component-package/src/MyComponent';
const meta: Meta<typeof MyComponent> = {
/* 👇 The title prop is optional.
* See https://storybook.org.cn/docs/configure/#configure-story-loading
* to learn how to generate automatic titles
*/
title: 'MyComponent',
component: MyComponent,
};
export default meta;
此外,如果您正在使用 TypeScript 进行开发,您可能需要更新 Storybook 的配置文件(即 .storybook/main.js|ts
)以包含以下内容
// Replace your-framework with the framework you are using (e.g., react-webpack5, vue3-vite)
import type { StorybookConfig } from '@storybook/your-framework';
const config: StorybookConfig = {
framework: '@storybook/your-framework',
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
typescript: {
// Overrides the default Typescript configuration to allow multi-package components to be documented via Autodocs.
reactDocgen: 'react-docgen',
check: false,
},
};
export default config;
如果您仍然遇到问题,我们建议使用默认的沟通渠道(例如 GitHub discussions)联系社区。
控件未在自动生成的文档中更新 Story
如果您通过 inline
配置选项关闭了 Story 的内联渲染,您将遇到关联的控件未在文档页面中更新 Story 的情况。这是当前实现的一个已知限制,将在未来的版本中解决。
了解更多关于 Storybook 文档的信息
- Autodocs 用于为您的 Story 创建文档
- MDX 用于自定义您的文档
- Doc Blocks 用于编写您的文档
- 发布文档 以自动化发布文档的过程