返回博客

Component Story Format 3 现已发布

新一代 story 格式,让您更高效

loading
Michael Shilman
@mshilman
上次更新

Stories 可视化组件在不同场景下的行为方式。Component Story Format (CSF) 是 story 的通用文件格式。

Component Story Format 3 标志着 story 的一次进化,它减少了样板代码并提高了人体工程学。这使得 story 更加简洁,编写速度更快。

我很高兴地宣布 CSF3 的正式发布。在为期 18 个月的 beta 期间,社区帮助我们找到了问题并改进了格式。从 Storybook 7 开始,CSF3 将成为编写 story 的默认方式。

改进包括

  • ♻️ 可扩展的 story 对象,方便轻松扩展 story
  • 🌈 简洁的默认渲染函数
  • 📓 方便的自动标题
  • ▶️ 用于脚本化交互和测试的 Play 函数
  • ✅ 100% 向后兼容 CSF 2

请继续阅读以了解有关该格式、自最初公告以来发生的变化以及如何在 Storybook 7 中充分利用它的更多信息。

等等,但是为什么?

在应用程序之外开发 UI 组件是创建高质量组件的最佳方法。Storybook 开创了这种组件驱动开发 (CDD) 风格。

现在,Stories 被设计师和产品经理用于视觉审查,以及用于设计系统文档、自动化测试,甚至从生产组件生成设计素材

毫不奇怪,Storybook 被用于在 Shopify、IBM 和 Salesforce 构建世界上许多最流行的 UI。

CSF3 是 story 的下一次进化——更易于编写和维护

与它的前身非常相似,CSF3 基于 ESM。默认导出包含有关组件的信息,以及一个或多个命名导出(stories)捕获不同的组件状态。主要区别在于,stories 现在是对象,您可以将 play 函数附加到每个 story 以模拟用户交互。

CSF3 完全向后兼容 CSF2,Storybook 7 仍然支持 CSF2。我们甚至已将 play 函数向后移植到 CSF2。

我们建议迁移,因为 CSF3 更具表现力和可维护性,并且您需要编写的样板代码更少。在大多数情况下,您可以使用 codemod 从 CSF 2 自动迁移到 3。

CSF3 功能回顾

大型项目可能由数百个组件和数千个 stories 组成。当您编写如此多的 stories 时,符合人体工程学的改进会带来明显的生活质量提升。我们的目标是简化 story 格式,使编写、阅读和维护 stories 更加容易。

让我们看看假设的 RegistrationForm 组件中的 CSF3 是什么样子的。

默认导出声明了您正在为其编写 stories 的组件

// RegistrationForm.stories.js

import { RegistrationForm } from './forms/RegistrationForm';

export default {
  title: 'forms/RegistrationForm',
  component: RegistrationForm,
};

现在 stories 是对象

export const EmptyForm = {
  render: (args) => <RegistrationForm {...args} />,
  args: { /* ... */ },
  parameters: {  /* ... */ },
};

简洁的默认渲染函数。 90% 的时间,编写 story 只是以标准方式将一些输入传递给您的组件。

在 CSF3 中,如果您未指定渲染函数,则每个 story 都会渲染组件并传入所有参数。这大大简化了您的代码。

在我们的 RegistrationForm 示例中,渲染函数是样板代码

export const EmptyForm = {
  // render: (args) => <RegistrationForm {...args} />, -- now optional!
  args: { /* ... */ },
  parameters: {  /* ... */ },
};

可重用的可扩展 story 对象。 当您尝试建模复杂状态时,能够扩展现有 stories 而不是重新编写它们会很有用。假设您想显示已填写的表单,但在不同的视口中

export const FilledForm = {
  args: {
    email: 'marcus@acme.com',
    password: 'j1287asbj2yi394jd',
  }
};

export const FilledFormMobile = {
  ...FilledForm,
  parameters: {
    viewports: { default: 'mobile' }
  },
};

用于脚本化交互的 Play 函数。 某些 UI 状态在没有用户交互的情况下是不可能捕获的。Play 函数在 story 渲染后运行,并使用 testing-library 模拟用户交互。例如

// RegistrationForm.stories.ts|tsx
import { userEvent, within } from '@storybook/testing-library';

// ...

export const FilledForm = {
  play: async ({ canvasElement }) => {
    const canvas = within(canvasElement);

    const emailInput = canvas.getByLabelText('email', { 
        selector: 'input' 
    });
    await userEvent.type(emailInput, 'example-email@email.com', { 
        delay: 100 
    });

    const passwordInput = canvas.getByLabelText('password', { 
        selector: 'input' 
    });
    await userEvent.type(passwordInput, 'ExamplePassword', { 
        delay: 100 
    });

    const submitButton = canvas.getByRole('button');
    await userEvent.click(submitButton);
  },
};

方便的自动标题。 在 CSF 中,story 的标题决定了它在 UI 中导航层次结构中的显示位置。在 CSF3 中,标题可以根据文件相对于根目录的位置自动生成。减少了输入,如果您重新排序文件,则无需更新任何内容。

export default {
  // title: 'forms/RegistrationForm' -- optional
  component: RegistrationForm,
};

有关 CSF3 功能和原理的深入描述,以及它与 CSF2 的确切区别,请参阅原始 CSF3 帖子

对原始版本的更改

在过去的一年半中,用户一直在他们的项目中测试 CSF3。根据反馈,我们对原始版本进行了一些更改。

更好的 TypeScript 类型。 我们已更新 7.0 中的 Meta/Story 类型,以支持 story 的类型安全和自动完成。请继续关注未来几周内有关此主题的专门帖子。

更新的自动标题启发式。 Autotitle 根据 CSF 文件的磁盘位置生成“标题”(Storybook 侧边栏中的路径)。例如,如果 /project/path/src 是 story 根目录,则 /project/path/src/atoms/Button.stories.js 将获得标题 atoms/Button。但是,朴素的启发式方法无法处理常见的模式,例如 atoms/Button/Button.stories.jsatoms/Button/index.stories.js。我们更新了启发式方法来解决这个问题。有关完整的迁移说明和包括更好的前缀处理和大小写在内的其他几项自动标题改进,请参阅 MIGRATION.md

升级的文档和 CLI 模板。 最后但并非最不重要的一点,我们已使用 CSF3 源代码片段升级了 7.0 的官方文档。我们还更新了 CLI 以为新项目生成 CSF3。

立即升级到 CSF3

CSF3 完全向后兼容,因此您现有的 CSF stories 仍然可以正常工作,无需修改。我们不会很快弃用旧格式。但是,CSF3 是向前迈出的一大步,我们建议您在升级到 Storybook 7.0 (SB7) 的同时升级您的 stories。

要升级到 SB7,请参阅我们的 SB7 迁移指南。升级项目后,您可以选择使用以下 codemod 将您的 CSF stories 迁移到 CSF3。请务必更新 glob 以包含您要更新的文件。

npx storybook@next migrate csf-2-to-3 --glob="**/*.stories.js"

如果您无法使用 codemod,我们还提供了升级说明

参与进来

Component Story Format (CSF) 帮助您隔离地开发、测试和记录组件。借助 CSF3,人体工程学得到了改进,可帮助您以更少的精力编写更多 stories。

CSF3 由 Michael Shilman(我!)、Kasper PeulenTom ColemanPavan Sunkara 开发,并得到了整个 Storybook 社区的测试和反馈。

Storybook 是 1600 多名社区贡献者的成果。在 GitHub 上加入我们,或在 Discord 上与我们聊天。最后,在 Twitter 上关注 @storybookjs 以获取最新消息。

加入 Storybook 邮件列表

获取最新的新闻、更新和发布信息

6,730位开发者及更多

我们正在招聘!

加入 Storybook 和 Chromatic 背后的团队。构建被数十万开发者在生产环境中使用的工具。远程优先。

查看职位

热门文章

Storybook 7 中改进的类型安全性

CSF3 语法与 TypeScript satisfies 结合使用,为您提供更严格的类型和改进的开发者体验
loading
Kasper Peulen

Storybook 7 文档

新架构、简化的用户体验和现成的文档块
loading
Tom Coleman

Vuetify in Storybook

通过开箱即用的 Vite 支持,充分利用 Storybook 中的 Vuetify
loading
Shaun Evening
加入社区
6,730位开发者及更多
为什么为什么选择 Storybook组件驱动的 UI
文档指南教程更新日志遥测
社区插件参与进来博客
案例展示探索项目组件词汇表
开源软件
Storybook - Storybook 中文

特别感谢 Netlify CircleCI