Skip to content

React-Vite: Add reactDocgenOptions for built-in react-docgen plugin#34454

Open
andrewsrigom wants to merge 3 commits intostorybookjs:nextfrom
andrewsrigom:feat/react-docgen-options
Open

React-Vite: Add reactDocgenOptions for built-in react-docgen plugin#34454
andrewsrigom wants to merge 3 commits intostorybookjs:nextfrom
andrewsrigom:feat/react-docgen-options

Conversation

@andrewsrigom
Copy link
Copy Markdown

@andrewsrigom andrewsrigom commented Apr 3, 2026

Closes #22565

What I did

  • added typescript.reactDocgenOptions to @storybook/react-vite
  • forwarded those options to the built-in Vite react-docgen plugin
  • added unit coverage for custom exclude and overridden include
  • documented the new config option in the TypeScript config docs

Checklist for Contributors

Testing

The changes in this PR are covered in the following automated tests:

  • stories
  • unit tests
  • integration tests
  • end-to-end tests

Manual testing

Manual testing not run locally.

Suggested verification steps:

  1. Run yarn start
  2. Open a React Vite sandbox and set typescript.reactDocgen to 'react-docgen'
  3. Add reactDocgenOptions: { exclude: [/Button\\.tsx$/] } to .storybook/main.ts
  4. Open the docs page for Button
  5. Confirm the component still renders, but docgen-derived props/argTypes are no longer inferred for the excluded component
  6. Remove reactDocgenOptions and confirm the generated props/argTypes return

Documentation

  • Add or update documentation reflecting your changes
  • If you are deprecating/removing a feature, make sure to update
    MIGRATION.MD

Summary by CodeRabbit

  • New Features

    • Configurable reactDocgenOptions for React+Vite projects (TypeScript main config now accepts reactDocgenOptions to control include/exclude scanning).
  • Documentation

    • Added docs and examples showing how to configure reactDocgenOptions in TypeScript-based Storybook main config.
  • Tests

    • Added tests verifying reactDocgen options are merged and respect user-provided precedence.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 3, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a40f813b-f916-4a69-9256-b3b5e268204a

📥 Commits

Reviewing files that changed from the base of the PR and between 030b0c8 and 29326aa.

📒 Files selected for processing (1)
  • code/frameworks/react-vite/src/preset.test.ts
✅ Files skipped from review due to trivial changes (1)
  • code/frameworks/react-vite/src/preset.test.ts

📝 Walkthrough

Walkthrough

Passes user-provided reactDocgenOptions from the React-Vite preset into the built-in react-docgen Vite plugin, adds a ReactDocgenOptions type, updates preset logic to merge options (respecting explicit include), adds tests for merging/precedence, and documents configuration snippets. (≤50 words)

Changes

Cohort / File(s) Summary
Preset implementation & types
code/frameworks/react-vite/src/preset.ts, code/frameworks/react-vite/src/types.ts
Add ReactDocgenOptions type, extend Typescript options with reactDocgenOptions, extract reactDocgenOptions from presets.apply('typescript', {}), and merge/spread reactDocgenOptions into the react-docgen plugin initialization (preserving explicit include).
Tests
code/frameworks/react-vite/src/preset.test.ts
New Vitest tests mocking react-docgen plugin: assert default include is applied when absent and that explicit reactDocgenOptions.include takes precedence; verify plugin ordering in resulting config.plugins.
Documentation & snippets
docs/api/main-config/main-config-typescript.mdx, docs/configure/integration/typescript.mdx, docs/_snippets/main-config-typescript-react-docgen-options.md
Document new optional reactDocgenOptions (include/exclude types) for TypeScript React configs and add example main.ts snippets demonstrating usage with both StorybookConfig and defineMain.

Sequence Diagram

sequenceDiagram
    participant User as User Config
    participant Preset as viteFinal Preset
    participant Plugin as react-docgen Plugin
    participant Vite as Vite Config

    User->>Preset: provide `reactDocgen` / `reactDocgenOptions`
    Preset->>Preset: presets.apply('typescript') -> extract reactDocgen, reactDocgenOptions
    Preset->>Preset: merge default `include` with reactDocgenOptions (skip if include provided)
    Preset->>Plugin: initialize `react-docgen` plugin with merged options
    Plugin->>Vite: insert plugin into `config.plugins`
    Vite->>Vite: use plugin options during build
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
code/frameworks/react-vite/src/preset.ts (1)

14-18: Consider improving type safety for the preset options.

Using <any> here loses type information for the destructured properties. While this works, it could mask issues if the preset shape changes.

♻️ Optional: Define an inline type for better type safety
-  const {
-    reactDocgen: reactDocgenOption,
-    reactDocgenOptions,
-    reactDocgenTypescriptOptions,
-  } = await presets.apply<any>('typescript', {});
+  const {
+    reactDocgen: reactDocgenOption,
+    reactDocgenOptions,
+    reactDocgenTypescriptOptions,
+  } = await presets.apply<{
+    reactDocgen?: 'react-docgen-typescript' | 'react-docgen' | false;
+    reactDocgenOptions?: Parameters<typeof import('./plugins/react-docgen.ts').reactDocgen>[0];
+    reactDocgenTypescriptOptions?: Parameters<typeof import('@joshwooding/vite-plugin-react-docgen-typescript').default>[0];
+  }>('typescript', {});
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@code/frameworks/react-vite/src/preset.ts` around lines 14 - 18, The
destructuring uses await presets.apply<any>('typescript', {}) which loses type
safety; define a small inline type or interface (e.g., TypeScriptPresetOptions
with reactDocgen, reactDocgenOptions, reactDocgenTypescriptOptions) and pass it
as the generic to presets.apply instead of any so the returned shape is typed
and the destructured variables (reactDocgenOption, reactDocgenOptions,
reactDocgenTypescriptOptions) have proper types.
code/frameworks/react-vite/src/preset.test.ts (1)

7-9: Consider using spy: true option for consistency with project mocking conventions.

As per coding guidelines, vi.mock() should use the spy: true option for file mocks. While the current approach works, adding the option maintains consistency with the repository's testing conventions.

♻️ Add spy option to vi.mock
-vi.mock('./plugins/react-docgen.ts', () => ({
+vi.mock('./plugins/react-docgen.ts', { spy: true }, () => ({
   reactDocgen: mocks.reactDocgen,
 }));

As per coding guidelines: "Use vi.mock() with the spy: true option for all package and file mocks in Vitest tests"

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@code/frameworks/react-vite/src/preset.test.ts` around lines 7 - 9, The test
mock for './plugins/react-docgen.ts' in preset.test.ts should follow project
conventions by adding the spy: true option to the vi.mock call; update the
existing vi.mock('./plugins/react-docgen.ts', () => ({ reactDocgen:
mocks.reactDocgen })) invocation to include the spy: true option so the mock is
registered as a spy while keeping the same factory that returns reactDocgen from
mocks.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@code/frameworks/react-vite/src/preset.test.ts`:
- Around line 7-9: The test mock for './plugins/react-docgen.ts' in
preset.test.ts should follow project conventions by adding the spy: true option
to the vi.mock call; update the existing vi.mock('./plugins/react-docgen.ts', ()
=> ({ reactDocgen: mocks.reactDocgen })) invocation to include the spy: true
option so the mock is registered as a spy while keeping the same factory that
returns reactDocgen from mocks.

In `@code/frameworks/react-vite/src/preset.ts`:
- Around line 14-18: The destructuring uses await
presets.apply<any>('typescript', {}) which loses type safety; define a small
inline type or interface (e.g., TypeScriptPresetOptions with reactDocgen,
reactDocgenOptions, reactDocgenTypescriptOptions) and pass it as the generic to
presets.apply instead of any so the returned shape is typed and the destructured
variables (reactDocgenOption, reactDocgenOptions, reactDocgenTypescriptOptions)
have proper types.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6ba580b8-2e37-48b2-8efc-a8fc33760240

📥 Commits

Reviewing files that changed from the base of the PR and between ce8c743 and 503017e.

📒 Files selected for processing (6)
  • code/frameworks/react-vite/src/preset.test.ts
  • code/frameworks/react-vite/src/preset.ts
  • code/frameworks/react-vite/src/types.ts
  • docs/_snippets/main-config-typescript-react-docgen-options.md
  • docs/api/main-config/main-config-typescript.mdx
  • docs/configure/integration/typescript.mdx

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
code/frameworks/react-vite/src/preset.test.ts (1)

21-34: Optional: extract duplicated presets.apply scaffold into a helper.

Both tests repeat the same presets.apply wiring. A tiny factory/helper would reduce noise and make future cases easier to add.

♻️ Suggested refactor
+const makeOptions = (reactDocgenOptions: Record<string, unknown>) =>
+  ({
+    presets: {
+      apply: async (name: string) =>
+        name === 'typescript'
+          ? { reactDocgen: 'react-docgen', reactDocgenOptions }
+          : undefined,
+    },
+  }) as any;
...
-    const config = await viteFinal({ plugins: [existingPlugin] }, {
-      presets: {
-        apply: async (name: string) => {
-          if (name === 'typescript') {
-            return {
-              reactDocgen: 'react-docgen',
-              reactDocgenOptions,
-            };
-          }
-
-          return undefined;
-        },
-      },
-    } as any);
+    const config = await viteFinal({ plugins: [existingPlugin] }, makeOptions(reactDocgenOptions));
...
-    await viteFinal({}, {
-      presets: {
-        apply: async (name: string) => {
-          if (name === 'typescript') {
-            return {
-              reactDocgen: 'react-docgen',
-              reactDocgenOptions,
-            };
-          }
-
-          return undefined;
-        },
-      },
-    } as any);
+    await viteFinal({}, makeOptions(reactDocgenOptions));

Also applies to: 49-62

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@code/frameworks/react-vite/src/preset.test.ts` around lines 21 - 34, Tests
duplicate the same presets.apply wiring when calling viteFinal; extract that
repeated scaffold into a small helper (e.g., createTypescriptPreset or
buildPresetApply) and use it in both test cases to reduce noise. Update the two
test blocks that call viteFinal so they pass the helper result instead of inline
apply: ensure the helper returns an object with apply: async (name: string) => {
if (name === 'typescript') return { reactDocgen: 'react-docgen',
reactDocgenOptions }; return undefined; } and reference this helper in the
viteFinal calls to replace the duplicated code.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@code/frameworks/react-vite/src/preset.test.ts`:
- Around line 21-34: Tests duplicate the same presets.apply wiring when calling
viteFinal; extract that repeated scaffold into a small helper (e.g.,
createTypescriptPreset or buildPresetApply) and use it in both test cases to
reduce noise. Update the two test blocks that call viteFinal so they pass the
helper result instead of inline apply: ensure the helper returns an object with
apply: async (name: string) => { if (name === 'typescript') return {
reactDocgen: 'react-docgen', reactDocgenOptions }; return undefined; } and
reference this helper in the viteFinal calls to replace the duplicated code.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 77d495cf-f11a-4fc8-919d-aa41b3b69056

📥 Commits

Reviewing files that changed from the base of the PR and between 503017e and 030b0c8.

📒 Files selected for processing (2)
  • code/frameworks/react-vite/src/preset.test.ts
  • code/frameworks/react-vite/src/preset.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • code/frameworks/react-vite/src/preset.ts

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Empathy Queue (prioritized)

Development

Successfully merging this pull request may close these issues.

[Feature Request]: A way to pass docgen options for JS projects

2 participants