文档
Storybook Docs

代码贡献

Storybook 的 monorepo 贡献新功能或错误修复。本页概述了如何设置您的环境以贡献代码。

先决条件

  • 确保您已安装 Node 版本 18 (建议版本:v18.16.0)。
  • 如果您使用的是 Windows,所有命令都应在具有管理员权限的终端中运行。

初始设置

首先,fork Storybook monorepo 并将其克隆到本地。

git clone https://github.com/your-username/storybook.git
cd storybook

Storybook 使用 Yarn 包管理器。使用 Corepack 为 Storybook 设置正确的版本。

corepack enable

运行您的第一个沙箱

Storybook 的开发是在一组“沙箱”环境中进行的,这些沙箱是与不同用户设置对应的模板化 Storybook 环境。在每个沙箱中,我们都会注入一组通用的 Story,以便我们能够测试所有这些环境中的核心功能和插件。

要在本地运行沙箱,您可以使用 start 命令。

yarn start

它将安装所需的先决条件,构建代码,创建并链接基于 Vite React 设置的入门示例,最后启动 Storybook 服务器。

如果一切顺利,您应该会看到沙箱正在运行。

Storybook sandbox running

运行不同的沙箱模板

默认情况下,start 命令配置为初始化一个基于 Vite 的 React 模板。如果您打算处理其他渲染器,也可以这样做。首先运行 task 命令,如下所示:

yarn task

在提示时,尽可能准确地回答问题,以便 Storybook 确定您的目标。回答完这些问题后,您应该会看到完整的命令以及您选择的选项,以便您需要时可以重新运行它。

yarn task 命令会采取一些开发捷径,这在切换分支时可能会让您感到意外,并且可能需要您重新运行 installcompile 任务。您可以通过运行带有 start-from=install 标志的命令来加快此过程。

运行测试

在成功运行您的 第一个沙箱 后,您的本地机器上应该已经有一个功能齐全的 Storybook 版本。在进行任何代码更改之前,验证一切是否正常工作至关重要——特别是测试套件。

运行以下命令来执行测试。

yarn test

开始开发

现在您已经 验证了您的设置,是时候开始编写代码了。最简单的方法是在一个终端窗口中运行一个沙箱,并在另一个单独的终端中运行交互式构建过程。

假设您仍在运行通过 yarn start 命令初始化的基于 Vite 的 React 沙箱,请打开一个新的终端窗口,导航到 Storybook monorepo 的 code 目录。然后,通过运行以下命令为您的贡献创建一个新分支:

git checkout -b my-first-storybook-contribution

最后,运行以下命令进行构建:

yarn build

当被询问是否以 watch 模式启动构建过程时,请回答 以进入交互式开发模式。之后,选择您要构建的包。例如,如果您要为 @storybook/addon-docs 开发一个功能,您可能需要同时选择 @storybook/addon-docsstorybook

构建的 watch 模式非常适合交互式开发。然而,出于性能原因,它只转译您的代码,而不执行 TypeScript 编译器。如果某个功能不起作用,请尝试在 启用 watch 模式的情况下运行 build 命令:它将重新生成 TypeScript 类型并执行自动类型检查。

Storybook package selector

如果您要进行的工作会影响 Preview(Storybook 的最内层 iframe,故事在此处显示),它会在您保存后的一到两秒内自动刷新。

否则,如果它会影响 Manager(Storybook 的最外层 iframe,插件在此处显示),您需要在保存后手动刷新。

Storybook manager preview

检查您的工作

完成编码后,添加适当的文档和测试。这可以简化 PR 的审查过程,意味着您的代码将更快地被合并。

添加 Story

向我们的套件添加 Story 或一组通用 Story 有助于您测试您的工作。

假设您正在处理 核心功能 之一,那么很可能已经存在一套完整的 Story。检查插件的 template/stories 目录,该目录记录了其工作原理,并在此处添加您的 Story。

如果您正在修改与特定渲染器(例如 React、Vue 3 等)相关的某些内容,它也将有一个类似的 template/stories 目录,您需要在其中添加您的 Story。

添加测试

单元测试确保 Storybook 不会意外损坏。如果您的代码可能以不明显的方式回归,请在您的拉取请求中包含单元测试。使用以下命名约定:

+-- parentFolder
|   +-- [filename].ts
|   +-- [filename].test.ts

端到端测试 (e2e)

Storybook 的 monorepo 设置为在 CI 中依赖端到端测试 Playwright。为了帮助测试,我们鼓励您在提交贡献之前运行此测试套件。

要针对沙箱运行 e2e 测试,您可以使用 e2e-tests 任务。

yarn task --task e2e-tests --template=react-vite/default-ts --start-from=auto

如果存在问题并且您想调试它们,您可以传递一个 DEBUG=1 环境变量,Playwright 将在 watch 模式下运行。

DEBUG=1 yarn task --task e2e-tests --template=react-vite/default-ts --start-from=auto

提交拉取请求

在提交您的贡献之前,最后一次运行测试套件,如下所示:

yarn test

Storybook 在其测试套件中依赖 Vitest。在测试运行时,如果您发现快照测试失败,请使用 -u 标志重新运行命令以更新它们。

这样做可以防止最后一刻的错误,并且一旦提交您的拉取请求,就可以更快地合并您的贡献。否则,维护者之一会将拉取请求标记为 正在进行中,直到所有测试都通过为止。

目标 next 分支

测试套件完成后,就可以提交、推送并打开一个拉取请求到 Storybook 的 next (默认) 分支。此分支是所有活动开发发生的地方,并关联到最新的预发布版本 (例如,7.0.0-alpha.47)。

如果您的贡献侧重于一个错误修复,并且您希望它出现在下一个稳定版本中,请在拉取请求描述中提及它。如果它看起来没有破坏性且修复了关键错误,我们将尝试将其修补。

处理 Fork 的有用资源

重现作业失败

创建 PR 后,如果 CI 作业之一失败,在检查该作业的日志时,您会看到它打印了一条消息,解释如何重现该任务。通常这涉及在正确模板上运行任务。

yarn task --task e2e-tests --template=react-vite/default-ts --start-from=install

通常,从 install 任务开始是个好主意,以确保您的本地代码完全是最新的。如果您重现了失败,您可以尝试进行修复,使用 build 进行编译,然后使用 --start-from=auto 重新运行任务。

默认指令在“链接”模式下运行代码,这意味着对 Storybook 库代码的更改会立即反映在沙箱中(下次运行任务时)。然而,CI 在“未链接”模式下运行,在极少数情况下,其行为会有所不同。

如果您在重现时遇到问题,请尝试使用 --no-link 标志重新运行命令。如果需要这样做,您需要在每次代码更改后使用 --start-from=compile 运行它。

如何处理重现

我们鼓励 Bug 报告包含重现。就像可以 在 monorepo 的示例项目上进行交互式开发 一样,也可以针对重现仓库进行开发。

为此,请在 monorepo 的根目录中运行以下命令:

npx storybook@next link https://github.com/your-username/your-project.git

此命令将创建一个项目 ../storybook-repros/your-project,并自动将其链接到您的本地 Storybook 代码。连接后,您应该能够运行 Storybook 并进行开发,如 上面 所述。

如果您已经在本地机器上有一个重现,您可以使用 --local 标志将其链接到您的 monorepo 开发设置:

npx storybook@next link --local /path/to/local-repro-directory

storybook link 命令在底层依赖 Yarn linking。它还要求您的本地重现使用 Yarn 2 或更高版本,如果您已经通过 storybook sandbox 命令启用了它,则情况就是如此。如果您尝试链接非 Yarn 2 项目,该过程将失败。

开发模板

第一步是在 code/lib/cli-storybook/src/sandbox-templates.ts 中添加一个条目,这是所有重现模板的主列表。

'cra/default-js': {
    name: 'Create React App (Javascript)',
    script: 'npx create-react-app .',
    inDevelopment: true,
    expected: {
      framework: '@storybook/cra',
      renderer: '@storybook/react',
      builder: '@storybook/builder-webpack5',
    },
  },

添加 inDevelopment 标志,直到 PR 合并(您可以稍后通过第二个 PR 来删除该标志),因为它将使开发过程更加轻松。

key cra/default-js 由两部分组成:

  • 前缀是用于生成重现应用的工具。
  • 后缀是修改默认安装的选项,例如特定版本或选项。

script 字段是生成应用程序环境的部分。 . 参数是“当前工作目录”,它会根据 key 自动生成(例如 repros/cra/default-js/before-storybook)。{{beforeDir}} key 也可以使用,它将被替换为该目录的路径。

其余字段不言自明。

skipTasks 字段存在是因为某些沙箱在特定任务中可能无法正常工作,但我们仍然希望运行其他任务。例如,引入了一个我们无法控制的错误,该错误仅在 test-runner 任务中失败。

name 字段应包含模板的人类可读名称/描述。

expected 字段反映了我们期望 sb init 生成的框架/渲染器/构建器。这对于生成沙箱时的断言很有用。例如,如果模板是用不同的预期框架生成的,它将失败,从而可以检测回归。

运行沙箱

如果您的模板具有 inDevelopment 标志,它将在沙箱过程中(本地)生成。您可以使用以下命令创建沙箱,其中 <template-key> 已替换为所选模板的 ID,例如 cra/default-js

yarn task --task dev --template <template-key> --start-from=install

具有 inDevelopment 的模板将自动使用 --no-link 标志运行,因为这是本地模板生成正常工作所必需的。

PR 合并后,该模板将以夜间模式生成,您可以删除 inDevelopment 标志,沙箱将从我们的模板仓库拉取代码。

故障排除

yarn build --all --watch 会监视所有内容,但资源消耗大。

事先知道将要更改哪些包很麻烦,并且即使在现代机器上,监视它们也可能非常耗费资源。如果您使用的是足够强大的机器,可以使用 yarn build --all --watch 而不是 yarn build

了解更多关于贡献 Storybook 的信息

  • RFC 流程,用于撰写功能请求。
  • 功能和错误修复的代码。
  • 框架,用于开始使用新框架。
  • 文档,用于文档改进、拼写错误和澄清
  • 示例,用于新代码片段