
使用 Nx 的 nx/react:stories 生成器为 React 项目批量生成 Storybook Stories【免费下载链接】nxThe Monorepo Platform that amplifies both developers and AI agents. Nx optimizes your builds, scales your CI, and fixes failed PRs automatically. Ship in half the time.项目地址: https://gitcode.com/GitHub_Trending/nx/nxnx/react:stories是 Nx React 插件提供的一个生成器它可以扫描指定 React 项目应用或库中的全部组件并自动为每个组件生成基于 Component Story Format 3 (CSF3) 为主干结合 stories.ts、component-story.ts 等源码与测试完整讲解该生成器的交互式提示、全部可用选项、路径过滤规则以及生成产物与底层实现原理帮助你在一分钟之内为整个项目的组件补齐 Storybook stories。生成器速览基本用法在 Nx 工作区中为某个项目生成 stories只需运行nx g nx/react:stories project-name命令中的project-name是必填参数指向你想要生成 stories 的 React 项目既可以是 application 也可以是 library。执行时Nx 会向你提出两个交互式问题提示对应选项说明For which project do you want to generate stories?name/project为哪个项目生成 stories必须提供Do you want to set up Storybook interaction tests?interactionTests是否同时配置 Storybook 交互测试默认开启第一个提示即项目名。第二个提示用于决定是否为生成的 stories 附加play函数交互测试并安装相关依赖。如果你希望跳过交互测试可以显式传入--interactionTestsfalse但从 Nx 的默认设计来看并不推荐——schema.json中该选项的默认值即为true见 stories/schema.json。你可以在 Storybook 概览页 找到生成器在 React 技术栈下的完整工作流程说明。完整选项清单除name和interactionTests之外该生成器还支持以下选项全部定义在 stories/schema.json 中选项类型默认值说明name别名project、projectNamestring无为哪个项目生成 stories必填可作为位置参数直接传入interactionTestsbooleantrue是否设置 Storybook 交互测试为true时在 stories 中加入play函数并安装依赖jsbooleanfalse是否生成 JavaScript.stories.js而非 TypeScript.stories.tsx文件ignorePathsstring[][*.stories.ts,*.stories.tsx,*.stories.js,*.stories.jsx,*.stories.mdx]扫描组件时忽略的路径glob 模式支持逗号分隔的字符串数组skipFormatbooleanfalse跳过生成后的代码格式化属于内部选项配置示例详解示例一忽略特定路径跳过不该独立的组件nx g nx/react:stories --nameui --ignorePathslibs/ui/src/not-stories/**,**/**/src/**/*.other.*这条命令会为ui项目中的所有组件生成 stories但排除两类文件libs/ui/src/not-stories目录下的所有文件文件名为*.other.*模式的所有组件例如header.other.tsx。ignorePaths使用 minimatch 语法做路径匹配支持单个字符串可包含多个逗号分隔的模式或字符串数组。schema.json中给出了几个常用的参考示例examples: [ apps/my-app/src/not-stories/**, **/**/src/**/not-stories/**, libs/my-lib/**/*.something.ts, **/**/src/**/*.other.*, libs/my-lib/src/not-stories/**,**/**/src/**/*.other.*,apps/my-app/**/*.something.ts ]这种过滤能力非常适用于“组件不适合被单独渲染”的场景比如某些组件必须作为更大组件的子部件、依赖外部上下文如路由、Provider才能工作把它们暴露成独立 story 反而会产生无法渲染或报错的条目。关于默认忽略规则Nx 默认会跳过已有的 stories 文件即以下模式不会被重复生成*.stories.ts, *.stories.tsx, *.stories.js, *.stories.jsx, *.stories.mdx也就是说你随时可以安全地重复运行生成器已经存在的 stories 不会被覆盖新加入的组件会被自动补齐。测试 stories.lib.spec.ts 中的ignore paths分组验证了这一行为——当传入ignorePaths时目标路径下的组件不再生成.stories.tsx而未匹配到的组件照常生成。示例二用 JavaScript 代替 TypeScript 生成 storiesnx g nx/react:stories --nameui --jstrue当项目本身是纯 JavaScript 的 React 代码时可以开启--jstrue。此时生成器会为组件生成.stories.js文件位于组件同级目录并采用 component-story 的 jsx 模板 中的 CommonJS/ESM 风格代码。默认值jsfalse则使用 TypeScript 模板见 tsx 模板生成.stories.tsx文件。生成器的工作原理与源码级解析理解底层实现有助于你预判生成结果。生成器的核心逻辑位于 stories.ts整体流程分为三步确定扫描目录 → 过滤候选文件 → 逐组件生成 story。第一步确定组件扫描目录projectRootPath函数会根据项目类型决定从哪个目录开始扫描组件应用application默认扫描源码根目录下的app子目录如apps/my-app/src/app如果识别出 Next.js 项目检测到next.config.js/next.config.ts或 Next 构建目标见isNextJsProject则改为扫描components目录库library扫描源码根目录下的lib子目录如libs/my-lib/src/lib其他情况直接扫描源码根目录。第二步过滤候选组件文件createAllStories使用visitNotIgnoredFiles遍历扫描目录并依次执行四道过滤跳过私有文件以_开头的文件如_helpers.tsx直接忽略应用ignorePaths任何命中传入 glob 模式的路径都被跳过见 stories.ts只保留组件文件仅处理.tsx/.js/.jsx且不是.spec.*测试文件的路径排除已有 story调用nx/storybook工具集中的isTheFileAStory判断文件是否已经是 story 文件同时检查同名的.stories.*文件是否已存在两者任一成立则跳过。其中isTheFileAStory的实现位于 packages/storybook/src/utils/utilities.ts它解析源文件的 import 声明只要检测到来自storybook/*的导入且导入中包含Story、Meta、storiesOf、ComponentStory或包含Storybook的标识符就判定该文件已是 story 文件。第三步为每个组件生成 story过滤得到的组件路径会并行调用componentStoryGenerator见 component-story.ts。在此之前containsComponentDeclaration会利用 TypeScript 的 AST 解析getComponentNode或findExportDeclarationsForJsx确认文件里确实声明了 React 组件——普通工具函数文件会被静默跳过不会报错这一点由测试should ignore files that do not contain components所验证见 stories.lib.spec.ts。生成的 story 长什么样以 TypeScript 模板为例生成的.stories.tsx具备以下骨架import type { Meta, StoryObj } from uiFramework; import { Button } from ./Button; import { expect } from storybook/test; const meta { component: Button, title: Button, argTypes: { // 从组件 Props 自动推断并填充 action onClick: { action: onClick }, }, } satisfies Metatypeof Button; export default meta; type Story StoryObjtypeof Button; export const Primary { args: { // 组件 Props 的默认值自动填充 }, } satisfies Story; export const Heading { args: {}, play: async ({ canvas }) { await expect(canvas.getByText(/Button/gi)).toBeTruthy(); }, } satisfies Story;几点值得注意模板中uiFramework由getUiFramework自动探测如storybook/react-vitecomponentName、props带默认值、argTypes带 action都是从组件源码的 AST 中动态提取的见 component-story.ts开启interactionTests时默认开启模板会追加一个带play函数的 story如Heading并引入expect来自storybook/test关闭后则不生成play与对应导入如果一个文件导出多个组件生成器会以组件名--导出名的方式命名 story 文件避免冲突生成完成后除非指定--skipFormattrue否则会调用formatFiles统一格式化所有生成的文件。与交互测试interaction tests配合使用交互测试是生成器默认打开的一项能力选择启用后play函数会被写进 stories同时storybook/test-runner版本与项目 Storybook 主版本匹配等依赖会被自动安装随后nx/storybook/plugin会为项目推断出test-storybook目标。撰写交互测试时你可以在play函数中使用storybook/test提供的expect、userEvent、within编写真实交互断言完整示例可参考 astro-docs/src/content/docs/kb/storybook-interaction-tests.mdoc。运行交互测试分为两步# 终端一先启动 Storybook保持运行 nx storybook my-project # 终端二再运行交互测试 nx test-storybook my-project测试运行器驱动的是“已在运行”的 Storybook 实例也可以使用--url将运行器指向已发布的 Storybook 地址。开发调试时可以直接在 Storybook 的 Interactions 面板中点击 play 按钮逐条运行并单步调试测试。Vite 驱动的框架也可以改用storybook/addon-vitest让test-storybook直接以 Vitest 方式运行而无需先启动 Storybook 服务要求 Storybook 10 及以上版本。常见问题与最佳实践重复运行是否安全安全。默认忽略规则已覆盖*.stories.*模式同名 story 不会重复生成新增组件会被增量补齐。如何避免为“非独立组件”生成 stories使用--ignorePaths精确排除或在文件命名上统一约定如*.other.*、_private/*配合_开头私有文件的默认跳过规则。何时使用--jstrue当项目代码为纯 JavaScript 且团队不维护.tsx组件时使用否则保持默认的 TypeScript 输出。跳过格式化的场景在脚本化批量生成多个项目串联时可传--skipFormattrue并在最后统一格式化减少重复 I/O。相关生成器如果整个项目尚未配置 Storybook可先用nx/react:storybook-configuration配置项见 storybook-configuration/schema.json完成.storybook目录、storybook/test-storybook/build-storybook目标与依赖安装再运行stories生成器批量产出 story 文件。【免费下载链接】nxThe Monorepo Platform that amplifies both developers and AI agents. Nx optimizes your builds, scales your CI, and fixes failed PRs automatically. Ship in half the time.项目地址: https://gitcode.com/GitHub_Trending/nx/nx创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考