Sanity 仓库的 Storybook 装配工作流:从 storybook-setup 技能到 dev/storybook 的真实实现
【免费下载链接】sanitySanity Studio – Rapidly configure content workspaces powered by structured content项目地址: https://gitcode.com/GitHub_Trending/sa/sanity
本篇聚焦 Sanity 仓库中名为storybook-setup的 Agent 技能:它规定了"Storybook 已安装之后,如何为真实组件生成可用的preview文件与 stories"的触发条件、前置检查与标准操作命令。结合仓库内dev/storybook这个已落地的 Storybook 工程(含.storybook/main.ts、.storybook/preview.tsx与 monorepo 集成配置),读者可以掌握一套可复用的 Storybook 配置装配流程,以及 monorepo 场景下让 stories 与真实包源码保持一致的关键细节。
一、这个技能解决什么问题,何时触发
SKILL.md 的 frontmatter 给出了明确的触发描述:
name: storybook-setup description: Use this skill when Storybook is already installed and the user wants a working `preview` file and stories for real components.注意它的边界定义:前提是 Storybook 已经安装,目标是产出一个"能用的preview文件"和"针对真实组件(而非占位 demo)的 stories"。这一定位把它和仓库中另外两个姊妹技能区分开,三者构成一条完整的装配链:
| 技能 | 触发条件 | 核心动作 |
|---|---|---|
| storybook-init | 项目中还没有 Storybook | 运行npm create storybook@latest安装,再npx storybook add @storybook/addon-mcp,随后转入/storybook-setup |
| storybook-setup | Storybook 已安装,需要可用 preview 与真实组件 stories | 运行npx storybook ai setup,严格遵循其输出 |
| storybook-upgrade | Storybook 已存在但版本过旧 | 按官方升级文档升级,目标是 10.5 或更高(未发布时可用npx storybook@next upgrade走预发布通道) |
从storybook-init的第三步可以看到三者的衔接关系:初始化成功后显式"Invoke the/storybook-setupskill",即 init 是入口、setup 是核心、upgrade 是版本兜底。
二、前置检查:两条硬性门槛
storybook-setup的 Prerequisites 部分只有两条,但每一条都有可验证的判定标准:
- 确认 Storybook 确实存在:检查项目里是否有
package.json中的 storybook 依赖和.storybook/目录。如果不存在,不应硬做配置生成,而应切换到/storybook-init走安装流程。 - 版本门槛:Storybook 必须至少是 10.5(若 10.5 尚未发布,则允许
next预发布版)。如果版本更旧,或者需要先升级/修复,切换到/storybook-upgrade。
仓库自身的配置正好满足并印证了这条门槛。在 pnpm-workspace.yaml 的 catalog 中:
storybook: ^10.6.0而 dev/storybook/package.json 同时引用了storybook: "catalog:"和@storybook/react-vite: ^10.6.0、@storybook/addon-vitest: ^10.6.0——版本线在 10.5 之上,符合技能设定的最低要求。这说明"版本前置检查"不是空话:storybook ai setup这类 AI 辅助命令在旧版本上能力有限,技能通过门槛把"配置问题"和"版本问题"拆到不同流程里处理,避免在错误的前提上生成配置。
三、标准操作:运行npx storybook ai setup,并严格遵循其输出
技能正文的核心指令只有两句,但纪律性极强:
Run `npx storybook ai setup` from the project root (or the Storybook package in a monorepo). **Follow the printed Markdown precisely.** Do not substitute your own plan.两个要点值得展开:
- 执行位置:从项目根目录运行;在 monorepo 中则从"Storybook 所在的那个包"运行。Sanity 仓库就是后者——Storybook 工程位于
dev/storybook,该目录有独立的package.json、.storybook/与tsconfig.json,命令应在该包上下文中执行。 - 遵循输出,而非自拟方案:
npx storybook ai setup会打印一份 Markdown 操作指引,技能要求执行者逐步照做、不得用自己的计划替代。这一条把"AI 生成配置"的不可控性收敛为"按机器输出的清单执行",是这类技能文档的典型防御性写法:生成质量取决于官方 CLI 的模板,执行者只负责忠实落地。
四、落地证据:dev/storybook中长出的 working preview
技能的目标产物是"a workingpreviewfile and stories for real components"。仓库里dev/storybook就是这条流程的完整实现,以下逐项对应。
4.1 包结构:Storybook 只拥有基础设施,stories 归属各包
dev/storybook/README.md 明确了职责划分:"Stories are package-owned and co-located"——dev/storybook只拥有 Storybook、Chromatic 与 addon-vitest 的基础设施,*.stories.tsx文件放在各个 workspace 包的src树中,与组件同目录。dev/storybook/.storybook/main.ts 的 stories glob 印证了这一点:
stories: ['../../../packages/{sanity,groq,@repo/*,@sanity/*}/src/**/*.stories.@(ts|tsx)'],即从dev/storybook向上三级到仓库根,再进入packages/下所有 workspace 包扫描 stories。这正是技能中"from the Storybook package in a monorepo"的实操形态:配置在 Storybook 包里,但被装配的对象是其他包的真实组件。
4.2 让 stories 像真实 studio 一样渲染:viteFinal是关键
main.ts 中最有深度的部分是viteFinal,它刻意对齐了packages/sanity/vitest.browser.config.mts:
async viteFinal(viteConfig) { return mergeConfig(viteConfig, { plugins: [vanillaExtractPlugin(), viteReact({compiler: {target: '19'}})], resolve: { conditions: ['monorepo', ...defaultClientConditions], dedupe: ['react', 'react-dom', 'sanity', 'styled-components', 'ui5'], }, }) }三个配置各有明确用途(源码注释亦如此说明):
resolve.conditions: ['monorepo', ...]:启用monorepoexports 条件,把 workspace 包解析到其 TypeScript 源码而非发布产物,保证 stories 构建的就是当前源码。vanillaExtractPlugin():支持.css.ts原子 CSS(仓库正在进行 styled-components → vanilla-extract 迁移,这是渲染前置条件)。viteReact({compiler: {target: '19'}}):应用 studio 自带(经oxc-transform-react)的 React Compiler 转换。
再加dedupe列表去重 React/studio 依赖,最终达到 README 的表述:"stories render exactly like the studio and the browser tests"。这是"working preview"在 monorepo 中的真正含义:不只是 Storybook 能跑起来,而是 stories 的渲染路径与真实产品一致,否则视觉回归结论没有意义。
4.3 工作可用的 preview:主题装饰器 + 固定视口 + autodocs
dev/storybook/.storybook/preview.tsx 展示了"为真实组件服务"的 preview 应包含什么:
import 'ui5/styles.css' import '@sanity/ui/styles.css' // ... const withStudioTheme: Decorator = (Story) => ( <ThemeProvider theme={studioTheme}> <ToastProvider> <LayerProvider> <Card style={{minHeight: '100vh'}} tone="default"> <Story /> </Card> </LayerProvider> </ToastProvider> </ThemeProvider> ) const preview: Preview = { decorators: [withStudioTheme], parameters: { layout: 'fullscreen', chromatic: { modes: { desktop: {viewport: {width: 1280, height: 900}} }, }, }, tags: ['autodocs'], }其中几个细节体现了"real components"的约束:
- 样式导入对齐 studio 入口:文件头注释说明,
ui5/styles.css与@sanity/ui/styles.css必须在 preview 层导入以对齐 studio 入口(packages/sanity/src/_exports/index.ts),否则直接引用源码的哨兵 stories 会漏掉 reset 与设计令牌。 - 装饰器复刻 studio 画布:
ThemeProvider+ToastProvider+LayerProvider+Card,给每个 story 与 studio 相同的基础层和主题化背景;嵌套的同主题ThemeProvider是被支持的 no-op。 - Chromatic 视口固定为 1280x900:刻意与 vitest browser-mode 测试的渲染视口一致,使如 Portable Text 工具栏在快照中显示全部按钮而非折叠进溢出菜单——跨两套快照系统(Storybook 与 vitest)保持一致基线。
layout: 'fullscreen'与tags: ['autodocs']:全屏布局 + 自动文档,且按 README 约定,所有 story 都保持可浏览、不以!dev等标签隐藏,因为 stories 本身是"组件如何被使用"的活文档。
4.4 命令与周边配置
技能流程完成后,日常操作由包内脚本承担(见 dev/storybook/package.json 与根 package.json):
# 仓库根目录 pnpm dev:storybook # 等价 pnpm --filter sanity-storybook dev → storybook dev --port 6006 --no-open pnpm build:storybook # pnpm exec turbo run build --filter=sanity-storybook # dev/storybook 目录内 pnpm test # vitest run,把每个 story 当浏览器模式测试跑(@storybook/addon-vitest) pnpm chromatic # 手动发布 + 快照(需要 CHROMATIC_PROJECT_TOKEN)周边配置也值得注意:turbo.json 声明build任务dependsOn: ["^build"],即构建 Storybook 前先构建上游 workspace 包;chromatic.config.json 开启onlyChanged只快照变更项;vercel.json 用cd ../.. && pnpm exec turbo run build --filter=sanity-storybook固定构建命令并把输出指向storybook-static,配合routes做 SPA fallback。
五、小结:把三条纪律带回你自己的项目
storybook-setup技能的篇幅虽短,但把装配流程压缩成了三条可迁移的纪律:
- 先验前提:确认
.storybook/存在、版本 ≥ 10.5,否则转去 init/upgrade 流程,绝不在错误前提上生成配置; - 命令标准化:统一用
npx storybook ai setup(monorepo 中在 Storybook 所在包内),并严格遵循其打印的 Markdown,不自拟替代方案; - 以真实组件为验收标准:preview 必须让 stories 以产品同款渲染路径运行(对齐 exports 条件、样式入口、视口与主题),
dev/storybook的 main.ts 与 preview.tsx 可直接作为 monorepo 场景的参照实现。
【免费下载链接】sanitySanity Studio – Rapidly configure content workspaces powered by structured content项目地址: https://gitcode.com/GitHub_Trending/sa/sanity
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考