文档
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 环境。在每个沙箱中,我们注入一组通用的 stories,使我们能够在所有这些环境中测试核心功能和插件。

要在本地运行沙箱,您可以使用 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-docs@storybook/components

构建的 watch 模式非常适合交互式开发。但是,出于性能原因,它仅转换您的代码,而不执行 TypeScript 编译器。如果某些内容未按预期工作,请尝试在**不**启用 watch 模式的情况下运行 build 命令:它将重新生成 TypeScript 类型并为您执行自动类型检查。

Storybook package selector

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

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

Storybook manager preview

检查您的工作

完成编码后,请根据需要添加文档和测试。这简化了 PR 审核流程,这意味着您的代码将更快地合并。

添加 stories

向我们的套件添加一个 story 或一组通用 stories 可帮助您测试您的工作。

假设您正在开发 Essential addons 之一,则可能已经存在完整的 stories 集。检查插件的 template/stories 目录,该目录记录了它的工作方式,并将您的 stories 添加到那里。

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

添加测试

单元测试确保 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 运行它。

如何使用复现

我们鼓励错误报告包含复现。就像可以在 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,这是所有 repro 模板的主列表

'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',
    },
  },

在 PR 合并之前添加 inDevelopment 标志(您可以使用第二个 PR 快速跟进以删除该标志),因为这将使开发过程更加容易。

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

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

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 的信息