Skip to content

React: Respect tsconfigPath option in react-docgen-typescript parser#34390

Closed
Muhammad-Nur-Alamsyah-Anwar wants to merge 3 commits into
storybookjs:nextfrom
Muhammad-Nur-Alamsyah-Anwar:fix-react-docgen-tsconfig-path
Closed

React: Respect tsconfigPath option in react-docgen-typescript parser#34390
Muhammad-Nur-Alamsyah-Anwar wants to merge 3 commits into
storybookjs:nextfrom
Muhammad-Nur-Alamsyah-Anwar:fix-react-docgen-tsconfig-path

Conversation

@Muhammad-Nur-Alamsyah-Anwar
Copy link
Copy Markdown

@Muhammad-Nur-Alamsyah-Anwar Muhammad-Nur-Alamsyah-Anwar commented Mar 29, 2026

Closes #34386

What I did

getParser() in reactDocgenTypescript.ts was hardcoded to always call findTsconfigPath(process.cwd()) for locating the TypeScript config. It completely ignored the tsconfigPath value that users can pass through reactDocgenTypescriptOptions in their Storybook config.

This broke monorepo setups where the root tsconfig.json uses project references with empty include/files arrays — the auto-detected tsconfig had no files listed, so react-docgen-typescript couldn't extract any component documentation.

The fix pulls tsconfigPath out of the user options and resolves it relative to process.cwd() when provided. When it's not set, the existing auto-detection behavior kicks in as before. I also made sure tsconfigPath gets stripped from the options object before it's forwarded to react-docgen-typescript, since it's not part of their ParserOptions type.

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

No automated tests added — the change is a small conditional branch in config resolution (tsconfigPath provided vs auto-detected), and the existing parser behavior is unchanged when the option isn't set. Best verified manually with an actual monorepo setup as described below.

Manual testing

Caution

This section is mandatory for all contributions. If you believe no manual test is necessary, please state so explicitly. Thanks!

  1. Set up a monorepo with a solution-style root tsconfig.json (empty include/files, only references)
  2. Create a separate tsconfig.storybook.json that explicitly includes the component source files:
    {
      "extends": "./tsconfig.base.json",
      "include": ["packages/*/src/**/*.ts", "packages/*/src/**/*.tsx"]
    }
  3. Configure .storybook/main.ts:
    typescript: {
      reactDocgen: 'react-docgen-typescript',
      reactDocgenTypescriptOptions: {
        tsconfigPath: './tsconfig.storybook.json',
      },
    },
  4. Run Storybook and check the Controls/Docs panel — component props should now be extracted correctly

Without this fix, step 4 shows no props because the auto-detected root tsconfig has no files to parse.

Documentation

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

Checklist for Maintainers

  • When this PR is ready for testing, make sure to add ci:normal, ci:merged or ci:daily GH label to it to run a specific set of sandboxes. The particular set of sandboxes can be found in code/lib/cli-storybook/src/sandbox-templates.ts

  • Make sure this PR contains one of the labels below:

    Available labels
    • bug: Internal changes that fixes incorrect behavior.
    • maintenance: User-facing maintenance tasks.
    • dependencies: Upgrading (sometimes downgrading) dependencies.
    • build: Internal-facing build tooling & test updates. Will not show up in release changelog.
    • cleanup: Minor cleanup style change. Will not show up in release changelog.
    • documentation: Documentation only changes. Will not show up in release changelog.
    • feature request: Introducing a new feature.
    • BREAKING CHANGE: Changes that break compatibility in some way with current major version.
    • other: Changes that don't fit in the above categories.

🦋 Canary release

This PR does not have a canary release associated. You can request a canary release of this pull request by mentioning the @storybookjs/core team here.

core team members can create a canary release here or locally with gh workflow run --repo storybookjs/storybook publish.yml --field pr=<PR_NUMBER>

Summary by CodeRabbit

  • New Features

    • Allow specifying an optional TypeScript configuration path for component manifest settings so custom tsconfig locations can be used.
  • Improvements

    • More reliable TS config resolution and loading with safer handling of user-provided options to avoid unintended parser configuration and to apply settings only when the config loads successfully.

@Muhammad-Nur-Alamsyah-Anwar Muhammad-Nur-Alamsyah-Anwar marked this pull request as ready for review March 29, 2026 11:05
Copilot AI review requested due to automatic review settings March 29, 2026 11:05
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes TypeScript config resolution for the React react-docgen-typescript parser used in component manifest/docgen extraction by honoring a user-supplied tsconfigPath (instead of always auto-detecting from process.cwd()), which unblocks solution-style monorepos.

Changes:

  • Respect reactDocgenTypescriptOptions.tsconfigPath by resolving it (relative to process.cwd()) and using it for readConfigFile/parseJsonConfigFileContent.
  • Strip tsconfigPath out of the options object before forwarding options to react-docgen-typescript (since it’s not part of their ParserOptions).
  • Keep existing auto-detection behavior (findTsconfigPath(process.cwd())) when tsconfigPath isn’t provided.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 29, 2026

📝 Walkthrough

Walkthrough

Prefer a user-provided tsconfigPath when creating the react-docgen-typescript parser, resolve it relative to the process CWD, only apply parsed TS config when read succeeded, and strip tsconfigPath from options before passing to the parser.

Changes

Cohort / File(s) Summary
react-docgen-typescript parser
code/renderers/react/src/componentManifest/reactDocgenTypescript.ts
Modify getParser to prefer userOptions.tsconfigPath (resolved via path.resolve(process.cwd(), ...)), capture readConfigFile error and conditionally apply compiler options/fileNames only when valid, and remove tsconfigPath from forwarded parser options.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs


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.

@valentinpalkovic valentinpalkovic added bug ci:normal manifest Component manifest generation labels Mar 30, 2026
@valentinpalkovic
Copy link
Copy Markdown
Contributor

valentinpalkovic commented Mar 30, 2026

Hi @Muhammad-Nur-Alamsyah-Anwar,

Thank you for your contribution.

I've looked up the issue and the mentioned configuration:

// .storybook/main.ts
const config: StorybookConfig = {
  typescript: {
    reactDocgen: 'react-docgen-typescript',
    reactDocgenTypescriptOptions: {
      tsconfigPath: './tsconfig.storybook.json',  // This is ignored!
    },
  },
};

Currently, config.typescript.tsconfigPath is not a documented option for react-docgen-typescript in Storybook. I see it is valuable, though. More info here: https://storybook.js.org/docs/api/main-config/main-config-typescript#reactdocgentypescriptoptions

We should update the documentation and internal typings (by removing the custom alias) to officially support the option.

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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
code/renderers/react/src/componentManifest/reactDocgenTypescript.ts (1)

203-209: ⚠️ Potential issue | 🟠 Major

Add error handling for tsconfig read/parse before building TypeScript program.

When configPath is provided (lines 203–208), readConfigFile() can return errors for invalid paths or malformed JSON, but the error is discarded via destructuring and config will be undefined. This flows into parseJsonConfigFileContent() without validation. With custom tsconfigPath now supported, users can easily hit this path with invalid input, causing unclear failures downstream.

The correct pattern already exists elsewhere in the codebase (reactDocgen/utils.ts): check readResult.error before using the config, and also validate parseJsonConfigFileContent().errors to surface issues early.

Suggested hardening
     if (configPath) {
-      const { config } = typescript.readConfigFile(configPath, typescript.sys.readFile);
-      const parsed = typescript.parseJsonConfigFileContent(
-        config,
+      const readResult = typescript.readConfigFile(configPath, typescript.sys.readFile);
+      if (readResult.error || !readResult.config) {
+        throw new Error(`Failed to read tsconfig at: ${configPath}`);
+      }
+      const parsed = typescript.parseJsonConfigFileContent(
+        readResult.config,
         typescript.sys,
         dirname(configPath)
       );
+      if (parsed.errors.length > 0) {
+        throw new Error(`Failed to parse tsconfig at: ${configPath}`);
+      }
       cachedCompilerOptions = { ...parsed.options, noErrorTruncation: true };
       cachedFileNames = parsed.fileNames;
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@code/renderers/react/src/componentManifest/reactDocgenTypescript.ts` around
lines 203 - 209, When configPath is provided, validate the result of
typescript.readConfigFile (do not destructure directly); capture its return
value (e.g., readResult) and if readResult.error is present surface/throw a
clear error before calling typescript.parseJsonConfigFileContent; after parsing,
check parsed.errors and surface/throw those errors as well so you never pass an
undefined config into typescript.parseJsonConfigFileContent or proceed to build
the TypeScript program; update the logic around configPath,
typescript.readConfigFile and typescript.parseJsonConfigFileContent in
reactDocgenTypescript.ts accordingly to fail fast with clear messages.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@code/renderers/react/src/componentManifest/reactDocgenTypescript.ts`:
- Around line 203-209: When configPath is provided, validate the result of
typescript.readConfigFile (do not destructure directly); capture its return
value (e.g., readResult) and if readResult.error is present surface/throw a
clear error before calling typescript.parseJsonConfigFileContent; after parsing,
check parsed.errors and surface/throw those errors as well so you never pass an
undefined config into typescript.parseJsonConfigFileContent or proceed to build
the TypeScript program; update the logic around configPath,
typescript.readConfigFile and typescript.parseJsonConfigFileContent in
reactDocgenTypescript.ts accordingly to fail fast with clear messages.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 690b3f81-5a4e-4e09-9b72-26ef8b437247

📥 Commits

Reviewing files that changed from the base of the PR and between bbe4cbd and 300233a.

📒 Files selected for processing (1)
  • code/renderers/react/src/componentManifest/reactDocgenTypescript.ts

@Muhammad-Nur-Alamsyah-Anwar
Copy link
Copy Markdown
Author

Fixed formatting and added error handling for invalid tsconfig files (matches existing pattern in utils.ts).

Let me know if you'd like me to add docs/types for the tsconfigPath option or if you'll handle that separately.

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/renderers/react/src/componentManifest/reactDocgenTypescript.ts (1)

203-214: Consider logging a warning when tsconfig cannot be read.

When typescript.readConfigFile returns an error, the code silently falls back to default compiler options. This could cause confusing behavior for users who provide an explicit tsconfigPath that fails to parse — they may not realize their config isn't being used.

Consider adding a warning using Storybook's logger:

💡 Optional improvement
+import { logger } from 'storybook/internal/node-logger';
+
 // ... in getParser function:
     if (configPath) {
       const { config, error } = typescript.readConfigFile(configPath, typescript.sys.readFile);
-      if (!error && config) {
+      if (error) {
+        logger.warn(`Failed to read tsconfig at ${configPath}: ${error.messageText}`);
+      } else if (config) {
         const parsed = typescript.parseJsonConfigFileContent(
           config,
           typescript.sys,
           dirname(configPath)
         );
         cachedCompilerOptions = { ...parsed.options, noErrorTruncation: true };
         cachedFileNames = parsed.fileNames;
       }
     }

As per coding guidelines: "Use Storybook loggers (storybook/internal/node-logger for server-side) instead of raw console.* methods in normal code paths."

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

In `@code/renderers/react/src/componentManifest/reactDocgenTypescript.ts` around
lines 203 - 214, The code silently ignores errors from typescript.readConfigFile
in reactDocgenTypescript.ts; update the block that calls
typescript.readConfigFile to log a warning when an error is returned (including
the error message and the configPath) instead of silently falling back, using
Storybook's server logger (e.g., the node/server logger import used across the
project such as logger from storybook/internal/node-logger or
`@storybook/node-logger`), and keep existing behavior of using default
cachedCompilerOptions/cachedFileNames when config parsing fails; refer to the
readConfigFile call, the parsed/ error destructuring, and the
cachedCompilerOptions/cachedFileNames variables to place the warning.
🤖 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/renderers/react/src/componentManifest/reactDocgenTypescript.ts`:
- Around line 203-214: The code silently ignores errors from
typescript.readConfigFile in reactDocgenTypescript.ts; update the block that
calls typescript.readConfigFile to log a warning when an error is returned
(including the error message and the configPath) instead of silently falling
back, using Storybook's server logger (e.g., the node/server logger import used
across the project such as logger from storybook/internal/node-logger or
`@storybook/node-logger`), and keep existing behavior of using default
cachedCompilerOptions/cachedFileNames when config parsing fails; refer to the
readConfigFile call, the parsed/ error destructuring, and the
cachedCompilerOptions/cachedFileNames variables to place the warning.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 82fdc2c0-4c2e-4d30-92e8-4835e3ee4419

📥 Commits

Reviewing files that changed from the base of the PR and between 300233a and bfaa03b.

📒 Files selected for processing (1)
  • code/renderers/react/src/componentManifest/reactDocgenTypescript.ts

@valentinpalkovic
Copy link
Copy Markdown
Contributor

Please add docs/types for the tsconfigPath option. That would be amazing. Thanks!

@gylxan
Copy link
Copy Markdown

gylxan commented Apr 27, 2026

@Muhammad-Nur-Alamsyah-Anwar Did you see the comment of @valentinpalkovic?
Would be nice, if we could fix the issue and merge the PR here ;)

@valentinpalkovic
Copy link
Copy Markdown
Contributor

Closing due to inactivity

@github-project-automation github-project-automation Bot moved this from On Hold to Done in Core Team Projects May 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug ci:normal manifest Component manifest generation Stale

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

[Bug]: getParser5() Ignores tsconfigPath Option

4 participants