Skip to content

[Bug]: getParser5() Ignores tsconfigPath Option #34386

@endurance-chorus

Description

@endurance-chorus

Describe the bug

Bug 1: getParser5() Ignores tsconfigPath Option

Summary

The getParser5() function in @storybook/react/dist/preset.js ignores the user-provided tsconfigPath option from reactDocgenTypescriptOptions and always uses findTsconfigPath(process.cwd()).

Impact

Users cannot specify a custom tsconfig for MCP manifest generation. This breaks:

  • Solution-style monorepos where tsconfig.json has empty include/files arrays
  • Projects needing different tsconfigs for different purposes (e.g., build vs. documentation)
  • Aggregated Storybook setups with stories from multiple packages that need a unified tsconfig
  • Custom tsconfig locations where the tsconfig isn't named tsconfig.json

Location

  • File: @storybook/react/dist/preset.js
  • Function: getParser5() (~line 11619)
  • Source Location: Likely in @storybook/react source under /src/preset.ts or similar

Reproduction link

Please review anyway - the bug + suggested fix is very very clear.

Reproduction steps

Reproduction Steps

  1. Create a solution-style TypeScript monorepo with root tsconfig.json:

    {
      "include": [],
      "files": [],
      "references": [
        { "path": "./packages/ui" },
        { "path": "./packages/app" }
      ]
    }
  2. Create a separate tsconfig for Storybook documentation:

    // tsconfig.storybook.json
    {
      "extends": "./tsconfig.base.json",
      "include": ["packages/*/src/**/*.ts", "packages/*/src/**/*.tsx"]
    }
  3. Configure Storybook with the custom tsconfig:

    // .storybook/main.ts
    const config: StorybookConfig = {
      typescript: {
        reactDocgen: 'react-docgen-typescript',
        reactDocgenTypescriptOptions: {
          tsconfigPath: './tsconfig.storybook.json',  // This is ignored!
        },
      },
    };
  4. Run Storybook and check MCP manifest output

  5. Observe: The custom tsconfig is ignored; manifest shows "No component file found" for all components

System

│
│  
│  Storybook Environment Info:
│

│  System:
│  OS: macOS 26.3.1
│  CPU: (16) arm64 Apple M4 Max
│  Shell: 5.9 - /bin/zsh
│  Binaries:
│  Node: 22.22.0 - /Users/enduranceidehen/.nvm/versions/node/v22.22.0/bin/node
│  Yarn: 1.22.22 - /Users/enduranceidehen/.nvm/versions/node/v22.22.0/bin/yarn
│  npm: 10.9.4 - /Users/enduranceidehen/.nvm/versions/node/v22.22.0/bin/npm
│  pnpm: 10.10.0 - /Users/enduranceidehen/.nvm/versions/node/v22.22.0/bin/pnpm
│  <----- active
│  Browsers:
│  Chrome: 146.0.7680.165
│  Safari: 26.3.1
│  npmPackages:
│  @storybook/addon-a11y: ^10.3.3 => 10.3.3
│  @storybook/addon-designs: ^11.1.3 => 11.1.3
│  @storybook/addon-docs: ^10.3.3 => 10.3.3
│  @storybook/addon-mcp: ^0.4.2 => 0.4.2
│  @storybook/addon-vitest: ^10.3.3 => 10.3.3
│  @storybook/react: 10.3.3 => 10.3.3
│  @storybook/react-vite: 10.3.3 => 10.3.3
│  @storybook/test-runner: 0.24.3 => 0.24.3
│  storybook: 10.3.3 => 10.3.3

Additional context

Current Behavior

function getParser5(userOptions) {
  let {
    shouldExtractLiteralValuesFromEnum,
    shouldRemoveUndefinedFromOptional,
    shouldIncludePropTagMap,
    savePropValueAsString,
    skipChildrenPropWithoutDoc,
    propFilter,
    shouldIncludeExpression,
    customComponentTypes
  } = {
    ...defaultOptions,
    ...userOptions
  };
  
  // BUG: Always uses findTsconfigPath, ignoring userOptions.tsconfigPath!
  let configPath = findTsconfigPath(process.cwd());
  
  // userOptions.tsconfigPath is destructured but NEVER used
  // ...
}

Expected Behavior

The function should respect user-provided tsconfigPath:

function getParser5(userOptions) {
  let {
    shouldExtractLiteralValuesFromEnum,
    shouldRemoveUndefinedFromOptional,
    shouldIncludePropTagMap,
    savePropValueAsString,
    skipChildrenPropWithoutDoc,
    propFilter,
    shouldIncludeExpression,
    customComponentTypes,
    tsconfigPath  // Destructure this!
  } = {
    ...defaultOptions,
    ...userOptions
  };
  
  // Use user-provided tsconfigPath if available
  let configPath = tsconfigPath 
    ? path.resolve(process.cwd(), tsconfigPath)
    : findTsconfigPath(process.cwd());
  
  // ...
}

Debugging Evidence

When adding console logging to the bundled code:

// In getParser5()
console.log('userOptions:', userOptions);
console.log('userOptions.tsconfigPath:', userOptions.tsconfigPath);  // Shows the path
console.log('configPath used:', configPath);  // Shows different path from findTsconfigPath()

Workaround

Modify the root tsconfig.json (the one found by findTsconfigPath()) to include all necessary source files directly, bypassing the solution-style pattern.

Suggested Fix

In the Storybook source code, update getParser5() to destructure and use tsconfigPath from userOptions.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions