Storybook 仓库内部开发工作流:重建并重启内部 Storybook UI 的 Agent 技能(rebuild-restart-storybook)
当你直接修改 Storybook 单仓库(monorepo)中 code/ 目录下的内部源码(core、addons、frameworks、renderers、libs 等)后,浏览器里跑着的内部 Storybook 不会自动感知这些变更——必须先重新构建受影响的包,再重启开发服务,才能看到最新的 UI。本文基于仓库中的 Agent 技能定义文件 SKILL.md,完整讲解这套「重建 + 重启 + UI Review」的标准工作流:每一步执行什么命令、为什么要在 code 目录下执行、如何用 Nx 项目名而不是 npm 包名来指定构建目标,以及端口被占用和 UI 复查(review)阶段的处理策略,帮助你(或你的 AI Agent)在修改内部 Storybook 代码后快速、正确地拿到可验证的最新界面。
技能定位与触发条件
rebuild-restart-storybook 是放在仓库 .agents/skills/ 目录下的一个 Agent 技能,其 frontmatter 声明如下(见 SKILL.md):
name: rebuild-restart-storybook:技能标识,也是用户可直接调用的斜杠命令/rebuild-restart-storybook;description:在修改内部 Storybook 代码(core、addons、frameworks、renderers、libs 等)之后重建并重启内部 Storybook UI,并可选地展示一次 UI review;适用于编辑了code/目录下任何包之后,或用户明确要求重建/重启 Storybook 的场景;allowed-tools: Bash, Read:该技能被限定只能使用 Bash 和 Read 两类工具——即它的实现完全由「读文件 + 跑命令」组成,不需要额外权限。
技能文档给出的适用前提非常明确:在改动内部 Storybook 代码之后遵循此工作流。这里的「内部 Storybook」指的是仓库自带的 dogfooding 实例——code/ 目录本身就是一个 Storybook 项目,它通过 workspace:* 依赖消费本仓库正在开发中的各个包(见 code/package.json 中对 @storybook/addon-a11y、@storybook/react、@storybook/builder-vite 等的 workspace:* 依赖),所以源码改动必须经过重新构建才能在这个实例中生效。
第 1 步:确认是否重建(针对模型调用场景)
技能第一步区分了两类触发方式:
- 用户显式运行了
/rebuild-restart-storybook——直接执行后续步骤; - 由模型(Agent)判断调用——必须先询问用户是否要重建并重启 Storybook,用户拒绝则到此为止。
这一步是典型的「破坏性/耗时操作前确认」设计:code/ 下的一次构建加重启可能耗时数分钟,且会占用 6006 端口、可能杀掉已在运行的实例,因此不应由 Agent 静默触发。
第 2 步:确定被修改的包及其 Nx 项目名
工作流的核心细节在于:构建目标要用 Nx 项目名来列举,而不是 package.json 里的 npm 包名。技能明确要求:对每个在会话中被修改过的包,进入该包目录读取 project.json,取其 name 字段作为项目名。
技能中的示例:若 code/addons/review 与 code/addons/vitest 被修改,则命令中的包列表为 addon-review addon-vitest。这一规则在仓库中可以直接验证:
| 包目录 | project.json 的 name |
对应 npm 包名(package.json) |
|---|---|---|
| code/addons/a11y | addon-a11y |
@storybook/addon-a11y |
| code/addons/vitest | addon-vitest |
@storybook/addon-vitest |
| code/renderers/react | react |
@storybook/react |
| code/core | core |
@storybook/core |
| code(聚合工程) | code |
@storybook/code |
从源码结构看,这种命名规则并非巧合:仓库顶层 package.json 声明的 yarn workspaces(code/addons/*、code/builders/*、code/frameworks/*、code/lib/*、code/renderers/* 等)与 Nx 工程一一对应,Nx 的 name 字段去掉了 @storybook/ 前缀并做了扁平化(例如 renderer 包的 Nx 项目名直接是 react)。因此在列举构建目标时,react 这样的短名是合法输入,而 @storybook/react 反而无法被识别。
第 3 步:按顺序执行构建与启动命令
技能规定了严格的执行顺序,全部在 code 目录下进行,<extra packages> 替换为第 2 步得到的项目名列表:
rm -rf node_modules/.cache
yarn
yarn build storybook <extra packages>
三条命令各自的作用:
rm -rf node_modules/.cache:清除 yarn/Nx 相关缓存,避免旧构建产物干扰;yarn:重新链接工作区依赖,保证workspace:*包指向最新源码布局;yarn build storybook <extra packages>:只构建「storybook 主包 + 本次修改的包」,而不是全量构建,这是整个工作流的提速关键。
yarn build 背后的构建管线
yarn build 最终落在 code/package.json 中的脚本(见 code/package.json):"build": "NODE_ENV=production yarn --cwd ../scripts build-package",而 scripts/package.json 里 "build-package": "jiti ./build-package.ts" 指向编排脚本 scripts/build-package.ts。阅读该脚本源码可以印证技能中「必须传对包名」这一要求:
- scripts/build-package.ts 用 commander 定义了
--all、--watch/--no-watch、--prod/--no-prod等选项,并将命令行位置参数与每个工作区包的「suffix」(即去掉@storybook/前缀后的名字,@storybook/cli特判为sb-cli)做匹配; - scripts/build-package.ts 对非法包名会做模糊匹配并输出
Did you mean xxx?提示后以非零码退出——所以传错 Nx 项目名时构建会快速失败,而不是静默跳过; - scripts/build-package.ts 对每个选中的包,以
code/<包目录>为 cwd 执行yarn exec jiti scripts/build/build-package.ts,并注入NODE_ENV=production,即逐包调用真正的构建实现 scripts/build/build-package.ts; - 若未传入任何包名,脚本会弹出交互式多选列表让你挑选(scripts/build-package.ts),这正说明 Agent 场景下显式传包列表的必要性。
后台启动内部 Storybook
构建完成后,技能要求在后台运行:
NODE_OPTIONS="--preserve-symlinks" yarn storybook:ui --no-open
其中 storybook:ui 定义在 code/package.json:NODE_OPTIONS="--max_old_space_size=4096 --trace-deprecation" core/dist/bin/dispatcher.js dev --port 6006 --config-dir ./.storybook。由此可知两个关键事实:
- 内部 UI 直接复用本地构建出的
core/dist/bin/dispatcher.js分发器以 dev 模式启动,配置目录是 code/.storybook(内含main.ts、preview.tsx、manager.tsx等完整配置); - 默认端口为 6006,这也是后文端口冲突处理的由来。
启动命令额外叠加的 NODE_OPTIONS="--preserve-symlinks" 用于让 Node 在解析 symlink 指向的包时保留真实路径(工作区链接场景下常见于 ESM 解析问题),--no-open 则避免在服务器/无头环境中尝试打开浏览器。
端口被占用时的处理
技能明确给出冲突处理策略:先取消本次启动,杀掉占用端口的旧进程释放端口,再重新启动 Storybook。从源码结构看,storybook:ui 固定绑定 --port 6006,没有自动换端口逻辑,因此「杀旧进程」是恢复可用的必要步骤,而非可选优化。
第 4 步:提供 URL 并询问是否需要 Review
Storybook 启动后,工作流要求把访问 URL(默认 http://localhost:6006,对应 storybook:ui 脚本中的 --port 6006)告知用户,然后询问是否要展示一次 UI review。这一步同样遵循「确认后再做」原则:review 会创建共享产物,是否执行由用户决定。
第 5 步:用 review-create MCP 工具展示 Review
用户确认后,技能指定使用 Storybook 的 review-create MCP 工具为相关 stories 创建一次 UI review,并给出两条挑选策略:
- 挑选与整个会话上下文相关的 stories 集合——即覆盖本次对话中实际触碰过的 UI 变更,让 review 有针对可比性;
- 如果没有相关 stories(因为本次没有改动任何 UI 元素),则反问用户想看哪部分内容的 review,而不是随便挑几个 stories 凑数。
关于 review-create 这一工具在仓库中的定位,可以从两处得到佐证:MIGRATION.md 的 API 迁移表中记录了旧名 display-review 更名为 review-create,说明它是随版本演进保留下来的官方 review 能力;而 agent-eval 评测框架(如 agent-eval/README.md 与 agent-eval/evals/802-create-component/EVAL.ts 中的 expectWorkflowCalls(['get-storybook-story-instructions', 'review-create']))把「创建组件后调用 review-create 发布 review」作为标准工作流断言,进一步印证该步骤在 Storybook 的 Agent 工作流中是约定俗成的收尾环节。
完整工作流速查
综合以上各步,修改内部 Storybook 源码后的标准流程可归纳为:
- 确认意图:用户显式执行
/rebuild-restart-storybook或直接同意重建; - 枚举改动包:逐个读取改动包的 project.json
name字段,得到 Nx 项目名列表(如addon-review addon-vitest); - 清理 + 安装 + 构建(均在
code目录):rm -rf node_modules/.cache→yarn→yarn build storybook <项目名列表>; - 后台重启:
NODE_OPTIONS="--preserve-symlinks" yarn storybook:ui --no-open(端口 6006,被占用时先杀旧进程); - 交付 URL + 可选 review:告知用户
http://localhost:6006,经确认后调用review-create为会话中相关 stories 创建 UI review。
这套技能的价值在于把「改完代码但界面没变」这一常见困惑转化为一条确定性的命令序列,并把包名映射、端口冲突、review 挑选这些容易出错的细节固化成规则——无论是人类维护者照着执行,还是 Agent 按步骤自动化,都能得到一致的结果。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00