Storybook CSF Factories 自动迁移:在 Monorepo / 多配置目录项目中用-c逐个执行automigrate csf-factories
【免费下载链接】storybookStorybook is the industry standard workshop for building, documenting, and testing UI components in isolation项目地址: https://gitcode.com/GitHub_Trending/st/storybook
CSF Next(工厂函数式 Component Story Format)以definePreview→preview.meta→meta.story的全链路工厂模式为 Storybook stories 提供端到端类型安全,而npx storybook automigrate csf-factories是把存量 CSF 3 故事文件自动改写到 CSF Next 的官方迁移命令。当代码库是 monorepo、包含多个互相独立的 Storybook 配置目录(例如apps/admin/.storybook与apps/website/.storybook)时,需要对每个配置目录单独执行迁移并通过-c指向它——这正是本文核心命令片段 docs/_snippets/csf-factories-automigrate-with-config-directory.md 所给出的用法。读完本文,你将掌握该命令在单项目与多配置目录场景下的完整调用方式、全部可用参数、其背后的 codemod 执行链路,以及如何用--dry-run等开关安全地落地迁移。
为什么需要“按配置目录”执行迁移
CSF Next 是 Storybook 对 Component Story Format 的下一次演进,官方文档将其描述为 preview 阶段特性(当前仓库中仍标记为 🧪 Preview,并提示 API 未来可能调整)。在该文档页面 docs/api/csf/csf-next.mdx 的 “Upgrade to CSF Next → Automatically” 一节中,官方给出的标准做法是:
- 单配置项目直接执行
npx storybook automigrate csf-factories(见无-c版本片段 docs/_snippets/csf-factories-automigrate.md); - 若项目存在多个 Storybook 配置,则对每个配置目录各执行一次,并用
-c参数指向对应的配置目录。
默认情况下 CLI 只会处理当前所在项目目录的 Storybook 配置(配置目录通常为.storybook)。monorepo 中每个工作区(workspace)都可能声明了自己的main.*、preview.*配置文件与一套独立的 stories 匹配规则,因此需要把“迁移到哪个配置项目”显式告诉 CLI,而不是依赖默认探测。
同时注意一个硬性前提:csf-factories自动迁移要求故事文件已处于CSF 3格式(自动迁移内部会先执行storybook migrate csf-2-to-3,见下文源码分析);如果你的存量文件还在 CSF 2,应先用 migrate-csf-2-to-3 片段 对应的迁移命令升级到 CSF 3。CSF Next 也支持“增量迁移”,无需一次性迁移全部故事文件,但同一个文件内不能混用新旧格式。
命令速查:逐配置目录执行迁移
下面命令来自源片段本身,三组分别对应 npm、pnpm、yarn 三种包管理器(Storybook CLI 通过对应包管理器拉取最新版 CLI 后执行)。假设 monorepo 中存在apps/admin与apps/website两个前端子项目:
npx storybook automigrate csf-factories -c apps/admin/.storybook npx storybook automigrate csf-factories -c apps/website/.storybookpnpm dlx storybook automigrate csf-factories -c apps/admin/.storybook pnpm dlx storybook automigrate csf-factories -c apps/website/.storybookyarn dlx storybook automigrate csf-factories -c apps/admin/.storybook yarn dlx storybook automigrate csf-factories -c apps/website/.storybook关键点拆解:
csf-factories是automigrate的可选fixId参数,表示“只运行 CSF Factories 这一个迁移项”。CLI 在启动时会打印Running csf-factories automigration,见 code/lib/cli-storybook/src/bin/run.ts 的action处理。-c <dir-name>即--config-dir,官方 help 描述为 “Directory of Storybook configurations to migrate”,值指向某子项目的 Storybook 配置目录(包含main配置与preview配置),示例中的路径均相对于该工作区根目录。- 每个配置目录对应一组独立探测与改写,因此示例把
apps/admin/.storybook与apps/website/.storybook分开执行。如果子项目之间有共享的 story 文件,请留意执行顺序与作用范围(glob 匹配规则见下文)。
手动逐个目录执行时的推荐操作顺序
若希望在 CI 或批量脚本中自动化,可先用以下组合先行核对、再实际改写:
npx storybook automigrate csf-factories -c apps/admin/.storybook -n # 仅检查并列出将要执行的迁移,不落地修改 npx storybook automigrate csf-factories -c apps/admin/.storybook -y # 跳过交互提问,直接执行automigrate命令的完整参数清单
本文命令在 CLI 上注册于command('automigrate [fixId]'),由 code/lib/cli-storybook/src/bin/run.ts 中的 commander 定义。与该场景直接相关的参数如下(均摘自当前仓库实现,而非文档杜撰):
| 参数 | 说明 |
|---|---|
[fixId] | 可选。指定只运行某一个迁移项,例如csf-factories;不传则检测并列出当前项目所有适用的迁移。 |
-c, --config-dir <dir-name> | 要迁移的 Storybook 配置目录(本文主题参数),例如apps/website/.storybook。 |
-y, --yes | 跳过交互提问。在csf-factories流程中,这会让“使用相对导入还是 subpath 导入”等提问不再弹出而直接采用默认/沙箱设定,避免 CI 卡在交互上。 |
-n, --dry-run | 只做检查与预演,不真正改写文件。 |
-l, --list | 列出当前可用的迁移列表。 |
--package-manager <type> | 强制指定包管理器(choices 枚举自仓库PackageManagerName),用于内部安装/执行命令。 |
-s, --skip-install | 跳过依赖安装步骤。 |
--renderer <renderer-pkg-name> | 显式指定 Storybook 使用的 renderer 包。 |
--skip-doctor | 跳过迁移前的 doctor 检查。 |
--glob <pattern> | 指定故事文件的匹配 glob(专门服务于csf-factoriescodemod,见后文)。 |
--debug/--loglevel <...>/--disable-telemetry等 | 由所有命令共享的通用日志与遥测选项。 |
其中-c与--config-dir是同一选项的短、长两种写法,父文档在 “Monorepos” 小节(docs/api/csf/csf-next.mdx)中对片段的原话是:如果你的项目有多个 Storybook 配置,就对该命令使用-c标志分别指向每个配置目录,它会按下方列出的人工升级步骤,在你全部的故事文件上逐一执行。
底层原理:一次automigrate csf-factories执行链路
该迁移项不是普通的“自动修复”,而是仓库中建模为CommandFix的命令型迁移(id: 'csf-factories'、promptType: 'command'),其实现集中在 code/lib/cli-storybook/src/codemod/csf-factories.ts。从源码看,一次执行大致分为五个阶段:
确认导入方式(story 文件里如何引用 preview 配置)
run()开始时,若没有--yes且不在沙箱环境,会弹出选择框询问 story 文件使用哪种导入:- 相对导入:
import preview from '../../.storybook/preview'; - Subpath 导入:
import preview from '#.storybook/preview'(Node.jsimports映射标准)。 源码同时提示:并非所有项目都适合 subpath 导入——某些 monorepo 布局、过旧 tsconfig、自定义 paths 或配置了类型别名插件的项目可能不兼容。
- 相对导入:
(可选)向
package.json写入imports映射当选用了 subpath 导入且主package.json尚未定义#*时,CLI 会在imports中追加映射:'#*': ['./*', './*.ts', './*.tsx', './*.js', './*.jsx'],然后写回 package.json。故事文件改写(stories codemod)对应
runStoriesCodemod:glob 默认是**/*.{stories,story}.{js,jsx,ts,tsx,mjs,mjsx,mts,mtsx}(可用--glob覆盖,否则非--yes模式下会交互式提问)。其执行顺序为:- 先跑
storybook migrate csf-2-to-3 --glob="..."把存量文件统一提升到 CSF 3; - 再对每个匹配文件执行
storyToCsfFactory(实现在 code/lib/cli-storybook/src/codemod/helpers/story-to-csf-factory.ts),改写为preview.meta+meta.story结构。 相关改写工具函数有专门的单元测试,见 code/lib/cli-storybook/src/codemod/helpers/csf-factories-utils.test.ts。
- 先跑
配置文件改写(main 与 preview)对
-c指向目录下的main配置执行configToCsfFactory({ configType: 'main', frameworkPackage }),把StorybookConfig改写为defineMain({...})(实现在 code/lib/cli-storybook/src/codemod/helpers/config-to-csf-factory.ts);随后对 preview 配置执行同类型改写,得到definePreview({ addons: [...] })形态。同步 addon最后通过
syncStorybookAddons把正在使用的 addon 同步进新的 preview 配置,使 addon 的类型注解能在整个项目中生效。
在“按配置目录”的层面,仓库的多项目调度逻辑位于 code/lib/cli-storybook/src/automigrate/multi-project.ts:每个被收集到的项目以configDir为键独立建模(ProjectAutomigrationData包含configDir、mainConfig、mainConfigPath、previewConfigPath、storiesPaths等),逐项目对每个 fix 执行check(),只有 check 通过(check_succeeded)的迁移才会进入确认与run();每个配置目录的最终状态会被记录为SUCCEEDED/FAILED/SKIPPED/UNNECESSARY等,见 code/lib/cli-storybook/src/automigrate/index.ts 及其端到端测试 code/lib/cli-storybook/src/automigrate/index.test.ts。
迁移完成后:你应该在 diff 中看到什么
父文档明确说明:automigrate csf-factories会把你此前手动升级到 CSF Next 的各步全部自动执行。因此改写完成后,git diff里大致应出现以下形态(这也是验证迁移是否成功的最小清单):
.storybook/main.*从export const config: StorybookConfig = {...}变为import { defineMain } from '@storybook/your-framework/node'+export default defineMain({...});.storybook/preview.*从export const preview: Preview = {...}变为import { definePreview } from '@storybook/your-framework'+export default definePreview({ addons: [...] }),并在preview.meta/meta.story中实现类型安全;- 故事文件开头由
import type { Meta, StoryObj }变为import preview from '../.storybook/preview',meta 从默认导出对象变为const meta = preview.meta({ component: Button, ... }),每个 story 由export const Primary = meta.story({...})生成; - 依赖同一个 story 展开新 story 的地方,会改由
<Story>.extend或通过Story.composed.args(相对导入被移动到composed属性下)复用属性; - 若使用了 Storybook 的 Vitest addon,
vitest.setup.*会更新为以preview.composed.beforeAll接管,且故事可被直接以Primary.run()的方式复用到测试文件。
上述每一步的完整 diff 示例都在父文档 docs/api/csf/csf-next.mdx 的 “Manual / 1~5” 各小节中逐条给出,可与自动迁移的产物相互对照。关于工厂函数核心语义(defineMain、definePreview、preview.meta、meta.story、<Story>.extend、<Story>.test、preview.type)以及.extend的属性合并规则(args浅合并、parameters深合并且数组整体替换、decorators与tags拼接),也均以该文档为准。
使用建议与注意事项
- 先 dry-run 再落地:首次对某个配置目录执行时,建议先加
-n观察输出,确认它检测到的是csf-factories这一项,再真正运行;脚本化场景建议配合-y与--skip-install避免交互中断(这些开关在 code/lib/cli-storybook/src/bin/run.ts 中均有注册)。 - 保持 Storybook 为最新版本:文档建议迁移前先执行
storybook upgrade升级 CLI 与相关包(预览特性依赖最新版实现)。 - 逐目录执行时留意 stories 作用域:codemod 按 glob 匹配故事文件,而 glob 的默认值相当宽(
**/*.{stories,story}...),多配置目录共享源码时,建议结合各项目main中的stories配置核对改写范围,必要时用--glob收窄,避免误改其他子项目的文件。 - 导入方式按项目实情选择:相对导入最保守;subpath 导入在 monorepo 包管理边界复杂、tsconfig 过旧或启用了自定义 paths / 类型别名插件的项目中可能解析失败,仓库实现会在提问阶段明确提示这一点。
- 迁移动作是幂等的、可审阅的代码改写:它不修改依赖运行时行为,只是重排故事文件与配置文件的语法结构;建议先提交一次基线 commit,便于 diff 审阅与回滚。
更多仓库内参考
- 本文主题命令片段:docs/_snippets/csf-factories-automigrate-with-config-directory.md
- 单配置目录版命令片段:docs/_snippets/csf-factories-automigrate.md
- 承载该片段的完整 CSF Next 参考与升级指南(含 “Monorepos” 小节):docs/api/csf/csf-next.mdx
automigrate命令注册与参数定义:code/lib/cli-storybook/src/bin/run.tscsf-factories命令型迁移实现:code/lib/cli-storybook/src/codemod/csf-factories.ts- story / 配置文件改写 helpers:code/lib/cli-storybook/src/codemod/helpers/story-to-csf-factory.ts、code/lib/cli-storybook/src/codemod/helpers/config-to-csf-factory.ts
- 多项目迁移调度与逐目录结果聚合:code/lib/cli-storybook/src/automigrate/multi-project.ts
- 迁移主入口及其端到端测试:code/lib/cli-storybook/src/automigrate/index.ts、code/lib/cli-storybook/src/automigrate/index.test.ts
- CSF 工厂模式核心运行时测试:code/core/src/csf/csf-factories.test.ts
【免费下载链接】storybookStorybook is the industry standard workshop for building, documenting, and testing UI components in isolation项目地址: https://gitcode.com/GitHub_Trending/st/storybook
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考