首页
/ Storybook 贡献开发全流程解析:从本地构建、测试、问题复现到发布的 CONTRIBUTING 指南

Storybook 贡献开发全流程解析:从本地构建、测试、问题复现到发布的 CONTRIBUTING 指南

2026-09-04 17:19:35作者:谭伦延

CONTRIBUTING.old.md 是 Storybook 仓库中保存的旧版贡献者指南,完整记录了一位社区贡献者从"跑起本地仓库"到"发布版本"所需掌握的全部实操路径:基于 yarn workspaces 的 monorepo 引导、单元测试与 Linter 配置、最小复现问题(monorepo 内外两条路线)、PR 提交与评审规范、Issue 分诊标签体系,以及面向维护者的预发布/正式发版命令序列。读完本文,你既能复现这份文档的每一步操作,又能对照当前仓库的 根 package.jsonscripts/package.json本地注册表实现 等源码,理解这些流程在今天的 Storybook 仓库中是如何演化落地的。

一、文档定位:一份面向贡献者的端到端操作手册

这份文档开篇即声明 Storybook 是"社区驱动项目",欢迎从讨论、文档到 bugfix、功能改进的各类贡献。其目录结构本身就勾勒出贡献者的完整工作流:

  • Issues:如何提 Issue、如何针对 main 分支验证问题、如何制作最小复现(monorepo 内 / monorepo 外两条路径)、测试更新规范;
  • Pull Requests (PRs):提交前检查、PR 提交者/评审者的职责;
  • Issue Triage:回复、打标、关闭 Issue 的规则;
  • Development Guide:环境前置条件、初始搭建(yarn bootstrap)、按包构建、kitchen sink 示例应用、在自己的项目中 link Storybook 包;
  • Release Guide:预发布(prerelease)与正式发布(full release)的命令序列。

文档同时给出了关键前提:仓库使用 yarn workspaces 管理,因此必须安装 yarn 作为包管理器。

二、Issues:提 Issue 与针对 main 分支验证

2.1 提 Issue 前的标准动作

文档要求贡献者在提 Issue 前:

  1. 先搜索现有 Issue 列表,若发现相同问题,用"thumbs-up reaction"投票以便维护者优先级排序;
  2. 否则新建 Issue,需包含:清晰的标题(越短越好)、清晰的描述、错误日志与截图;
  3. 为进一步加速修复,提供一个能复现问题的 sample repo

2.2 针对 main 分支测试的完整步骤

文档给出了"clone → 构建 → 测试/lint"的标准流程:

git clone https://github.com/storybookjs/storybook.git
cd storybook
yarn bootstrap

文档特别提示:在 Windows 上可能需要先运行一次 yarn 再执行 yarn bootstrapyarn bootstrap 会交互式询问要引导(bootstrap)哪些代码区块,保持默认即可;也可以直接用 CLI 参数指定,例如 yarn bootstrap --core

单元测试(2a 节)yarn test 会列出所有可运行的测试套与选项,支持 --watch(监听模式)、--coverage(覆盖率)、--runInBand(串行运行)等参数,也可以用 --update(或 jest -u)更新快照。其中 yarn test 默认执行 <rootdir>/app/react<rootdir>/app/vue<rootdir>/lib 三处的测试,运行前需先用 yarn bootstrap --core 完成 core 引导。

Windows 用户还需注意:将 core.autocrlf 设为 falsegit config --global core.autocrlf false),避免覆盖快照中的换行符;文档还建议尽量在 WSL2 中运行测试,规避 unix 风格路径问题。

Linter(2b 节):仓库对所有代码(含 TypeScript)统一使用 ESLint,运行 yarn lint 即可。文档还附上了 VsCode 的推荐配置,启用保存时自动修复与缓存:

{
  "editor.codeActionsOnSave": { "source.fixAll.eslint": true },
  "eslint.packageManager": "yarn",
  "eslint.options": {
    "cache": true,
    "cacheLocation": ".cache/eslint",
    "extensions": [".js", ".jsx", ".json", ".html", ".ts", ".tsx", ".mjs"]
  },
  "eslint.alwaysShowStatus": true
}

对照当前仓库:今天的仓库已迁移到 yarn 4(见 根 package.json 中的 "packageManager": "yarn@4.18.0"),测试器从 jest 换成了 vitest——根目录 test 脚本为 NODE_OPTIONS=--max_old_space_size=4096 vitest runvitest.config.ts 通过 projects 字段聚合了 code/corecode/addons/*code/frameworks/*code/renderers/*scripts 等子项目的 vitest 配置;lint 也从 ESLint 换成了 oxlint(code 工作区的 lint:js:cmdoxlint --report-unused-disable-directives-severity=error,见 code/package.json)。旧文档的"跑测试 + 跑 lint"工作流思想完全延续,只是具体工具链演进到了 vitest/oxlint。

三、Reproductions:两条最小复现路径

3.1 在 monorepo 内复现

文档推荐的最佳复现方式是:直接在本仓库内嵌的官方示例应用上做改动。步骤为:

git clone https://github.com/storybookjs/storybook.git
cd storybook
yarn
yarn bootstrap --core

# 在示例应用中做改动以尝试复现问题(如添加组件 + stories)
cd examples/official-storybook
yarn storybook

# 若成功复现,提交到一个描述性分支
git checkout "branch-describing-issue"
git add -A
git commit -m "reproduction for issue #123"

# 将 storybook 仓库 fork 到你自己的账号,添加 remote 后推送
git remote add <your-username> https://github.com/<your-username>/storybook.git
git push -u <your-username> next

之后在 Issue 中链接到该 fork 仓库即可。文档还特别提醒:若问题涉及 webpack 配置,create-react-app 会阻止你修改应用自身的 webpack 配置,但可以修改 storybook 侧的配置来镜像你应用的情况;或者在 CRA 应用里 yarn eject 以获得可修改的 webpack 配置。

对照当前仓库:仓库中的示例目录已从 examples/ 演进为 test-storybooks/(如 test-storybooks/portable-stories-kitchen-sink/test-storybooks/mcp/),并通过 code/sandbox/ 下的大量 *.json 沙盒配置(react-vite、vue3-vite、nextjs、svelte-vite 等)配合 scripts 中的沙盒生成脚本 统一管理。"kitchen sink"这一概念被完整保留并体系化。

3.2 在 monorepo 外复现:本地 npm 注册表

当你的 Storybook 深度嵌入自有工程、难以做独立最小复现时,文档介绍了仓库内置的"本地注册表"脚本,它的工作原理是:

  • 在你本机启动一个 npm 注册表;
  • 把你的默认 registry 指向这个本地注册表;
  • 构建 Storybook 仓库中的所有包;
  • 将所有包以 latest 版本发布到本地注册表。

只要保持注册表进程运行,你就可以随时从它安装 Storybook 包;修改 Storybook 代码后,重新触发构建(yarn devyarn bootstrap --core 保证转译),在注册表终端按 <Enter> 触发重新发布,再回到你的项目重装依赖并重启 Storybook 即可。文档还解释了为何不直接用 npm link:link 繁琐,且与基于 registry 的安装存在细微差异,可能掩盖真实问题。

源码级印证:这条路线在今天的仓库中对应 scripts/run-registry.ts(由 scripts/package.json"local-registry": "jiti ./run-registry.ts" 脚本暴露,也可从 code 工作区用 yarn local-registry 触发)。阅读其实现可以看到它比文档描述更精巧:

  • 使用 Verdaccio 作为本地注册表,监听 6002 端口;
  • 在 6001 端口再起一个代理服务器:URL 中包含 storybook/sb 或方法为 PUT(发布)的请求 302 转发到本地 Verdaccio,其余流量直接转发到公共 npm 注册表——源码注释解释这样做的动机是"把所有流量都走 Verdaccio 代理会很慢,用这个启发式规则可以两全其美";
  • Verdaccio 的具体包路由规则定义在 scripts/verdaccio.yaml:所有 @storybook/*storybooksbcreate-storybookeslint-plugin-storybook 等包不代理到上游注册表(源码注释明确"允许我们在测试期间重新发布任意版本"),而 @*/*** 则统一 proxy: npmjs

这份 yaml 同时列出了数十个 legacy/外部 @storybook/* 包(如 @storybook/bench@storybook/addon-styling@storybook/testing-library),与 run-registry.ts 一起构成了一条可验证的"文档流程 → 仓库实现"证据链。

四、Updating Tests 与 PR 规范

4.1 测试更新约定

文档要求:任何 PR 提交前必须新增或更新有意义的测试;带失败测试的 PR 会被视为"Work in Progress",在所有测试通过之前不予合并。新建单元测试文件需遵循目录与命名约定:

# js 测试文件的正确命名与结构
+-- parentFolder
|   +-- [filename].js
|   +-- [filename].test.js

4.2 PR 提交者与评审者

  • 提交者:提交前必须确保 yarn test 通过,测试失败不要提交 PR;PR 需关联对应 Issue、附简短贡献描述;代码类改动需附上手动测试步骤(文档提到这些要求由 PR 模板非正式地强制)。若评审认为只差琐碎修改(如小笔误),且你有 commit 权限,可以自己改完合并。
  • 分支策略:文档特别注明——虽然最新稳定版对应 main 分支,但几乎全部 Storybook 开发发生在 next 分支,因此 PR 应从 next 拉出并指向 next
  • 评审者:通读改动、指出潜在问题、按提交者给的手动测试步骤实际验证;若步骤缺失、模糊或过于复杂,可要求提交者补充;除非 PR 带有 do not merge 标签,批准评审且无其他待办后应直接合并。

五、Issue Triage:标签体系与关闭规则

文档将 Issue 分诊归纳为三层操作:

回复 Issue:带 question / supportneeds reproduction 标签的 Issue 是最佳切入点——回答别人的问题既能帮提问者,也方便后来者搜索命中;需要复现的 Issue 可以引导报告者按上文复现技术制作复现,或自己动手。

打标签:标签分为三类——

维度 取值示例 说明
type bugfeaturequestion / supportdiscussiondependenciesmaintenance 每个 Issue 必须有且仅一个 type 标签;dependencies 用于依赖升级,maintenance 是清理/重构的兜底类
area addon: xaddons-apistories-apiui 一个或多个,用于按模块过滤
status needs reproductionneeds PRin progress 一个或多个,用于控制开放 Issue 总量

bug 类 Issue,若没有你亲自确认过的清晰复现,应打上 needs reproduction 并请作者制作复现(或自己尝试)。

关闭规则:重复 Issue 附原 Issue 链接后关闭;无法复现且报告者失联约两周后关闭;bug 合入后打 merged 标签,修复并发布后关闭;question / support 在问题被回答后关闭(失联者同样等待两周);discussion 由维护者酌情关闭。

这一整套 triage 机制在 CONTRIBUTING.md 的现行版本中依然延续了"标签 + 状态"的思路,属于 Storybook 社区治理中长期稳定的部分。

六、Development Guide:本地开发环境搭建

6.1 前置条件与初始搭建

前置条件:最新稳定版的 node 与 yarn(文档注明遇到搭建问题时确认 node/npm/yarn 均为最新,yarn 至少 v1.3.2)。初始步骤:

  1. git clone https://github.com/storybookjs/storybook.git(建议用你自己的 fork);
  2. cd storybook
  3. yarn bootstrap --core(Windows 上可能需要在第 2、3 步之间先跑一次 yarn)。

bootstrap 会静态构建整个项目。为了让 Storybook 代码的改动实时反映到 examples 下的示例应用中,文档给出两种方式:

  • yarn dev:监听全部包——文档坦承这"极其慢";
  • yarn build <package1> <package2> --watch:只监听指定的固定包列表,例如 yarn build add-docs components --watch(对应 @storybook/addon-docs@storybook/components),在较慢的机器上更实用。

完整 bootstrap(慢)yarn bootstrap --all → 休息片刻 → yarn test 验证一切正常。

按包构建:文档给出了 yarn build 的完整 CLI 语义——

  • 裸跑 yarn build:交互式列出可构建的包供选择,并支持 watch 模式选项;
  • yarn build <package-name>:构建指定包,包名用短名,如 @storybook/addon-docs 对应 yarn build addon-docs
  • yarn build --all:构建全部;
  • 追加 --watch:按名构建或全量构建时进入 watch 模式,如 yarn build core addon-docs --watch

对照当前仓库:当前 code 工作区(code/package.json)的构建入口为 yarn build(委托到 scripts/build-package.ts),日常开发则统一走 nx 驱动的 yarn task(见 scripts/task.ts,根 package.json 中的 start 脚本即 yarn task --task dev --template react-vite/default-ts --start-from=install)。yarn bootstrap / yarn build 时代已让位于 task 流水线,但"选包构建 + watch 模式"的交互语义是一致的。

6.2 在 kitchen sink 应用中开发

文档指出:仓库 examples 目录下为 Storybook 支持的各种平台提供了"厨房抽屉"(kitchen sink)级实现示例,它们不仅展示了大量选项与 add-on,而且自动链接到所有开发中的包,文档强烈建议贡献者在其中开发/测试自己的改动。以 React 和 Vue 为例:

cd examples/official-storybook
yarn storybook
# 验证本地版本工作正常

当前仓库中,这一角色由 test-storybooks/ 目录(portable-stories-kitchen-sinkmcpexternal-docsyarn-pnp 等)与 code/sandbox/ 下的 40 余个沙盒配置共同承担,e2e 测试(code/e2e-sandbox/code/e2e-internal/)则跑在这些沙盒之上。

6.3 在自己的应用中 link Storybook

文档以 @storybook/react 为例说明分包安装的 link 流程:

Link 步骤(注意:必须进入子项目目录内执行 yarn link不要在 storybook 根目录执行):

cd app/react
yarn link

把自己的项目接入(前提是 yarn dev 正在运行):

  1. 在你的项目中 getstorybook 安装 Storybook 并 yarn storybook 验证本地版本可用;
  2. 回到 storybook 根目录,等待 yarn dev 的输出停止(改动会转译到 dist 并在此记录);
  3. 进入你的沙盒项目目录,执行 yarn link @storybook/react,再 yarn storybook

文档提醒:link 后若看不到 add-on,多半是版本问题,需把你用到的每个 add-on 也逐一 link(这对 kitchen sink 应用和自有项目都适用)。最后到 http://localhost:9011(或 Storybook 实际运行端口)验证改动生效,若看不到改动则重跑 yarn storybook

6.4 文档开发

文档说明:Storybook 官方文档站点由独立的 frontpage 项目承载,但文档源文件位于本仓库(今天对应 docs/ 目录)。查看开发中文档的改动需使用 frontpage 项目文档中描述的"linking"方式。

七、Release Guide:维护者发布流程

这一节面向执行发布的 Storybook 维护者,前提假设:yarn >= 1.3.2,且已从 storybookjs/pr-log 项目 link 了 pr-log 工具。文档声明这是"面向未来 CI 自动化的手动序列",并自注"未完成,不懂勿试"。核心序列为:生成并人工核对 changelog → 推送 changelog 到 main 或 release 分支 → clean、build、publish → 把 changelog 粘贴到 GitHub Release 页面并标记为(预)发布

文档还指出一个关键细节:首次发布一个 scoped 包(@storybook/x)时,其 package.json 必须包含:

"publishConfig": {
  "access": "public"
}

7.1 Prerelease(预发布)序列

# 确保与 origin/next 同步
git checkout next
git status

# 生成 changelog(产生一个 Next 小节)并按需编辑
yarn changelog:next x.y.z-alpha.a

# 按需编辑 changelog/PR 列表后提交
git commit -m "x.y.z-alpha.a changelog"

# 干净构建
yarn bootstrap --reset --core

# 发布并打 tag
yarn run publish:next

# 更新 GitHub Release 页面

7.2 Full release(正式发布)序列

# 确保与 origin/main 同步
git checkout main
git status

# 生成 changelog(产生一个 vNext 小节)并按需编辑
yarn changelog x.y.z

# 按需编辑后提交
git commit -m "x.y.z changelog"

# 干净构建
yarn bootstrap --reset --core

# 发布并打 tag
yarn run publish:latest

# 更新 GitHub Release 页面

对照当前仓库changelog/changelog:next 这两个脚本名在 code/package.json 中依然存在(pr-log --sloppy --cherry-pickpr-log --sloppy --since-prerelease),而发布环节已脚本化为一组 release:* 命令(见 scripts/package.json):release:versionrelease:write-changelogrelease:get-changelog-from-filerelease:is-prereleaserelease:is-pr-frozenrelease:publish 等,核心发布逻辑在 scripts/release/publish.ts。从源码可以看到它强制要求 -T, --tag 参数(注释解释"留空会以 latest tag 发布,故必须显式指定"),并通过 yarn workspaces foreach --all --parallel --no-private ... npm publish --provenance --tolerate-republish --tag <tag> 完成带 provenance 的并行发布,还内置了 3 次重试与 15 分钟注册表轮询等待(REGISTRY_POLL_TIMEOUT_MS)。旧文档"先 changelog、后 clean build、再 publish、最后更新 Release 页面"的四段式流程,正是这套自动化的雏形。

另外可参照仓库内的发布记录文件了解真实版本节奏:CHANGELOG.md(正式版本)、CHANGELOG.prerelease.md(预发布),以及现行 CONTRIBUTING.md 中面向自动化发布流程的配套说明。

八、小结:这份旧指南留下的可复用资产

  • Monorepo 贡献方法论bootstrap --core 引导 → 选包 watch 构建 → kitchen sink 应用验证 → 测试与 lint 全绿后提 PR,这套"本地全链路验证"的思路至今不变;
  • 本地注册表复现方案:文档中"起本地 registry + 发布为 latest + 代理分流"的设计,在 scripts/run-registry.tsscripts/verdaccio.yaml 中得到源码级落实,6001 代理端口/6002 Verdaccio 端口的分流启发式至今仍在使用;
  • 社区治理三件套:Issue 标签体系(type/area/status)、"测试不过不合并"的 PR 门槛、维护者 changelog-driven 的发布序列,构成了 Storybook 作为大型开源 monorepo 的协作基础设施。

对于今天想参与 Storybook 开发的读者,建议将本文作为"历史基线",再结合现行 CONTRIBUTING.mdAGENTS.md 获取最新的命令与流程变更——旧指南中的每个环节,都能在现行仓库的脚本与配置中找到对应实现。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
527
590
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
904
1.82 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
docsdocs
暂无描述
Markdown
889
5.78 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.52 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.33 K
1.45 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
980
502
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384