From 191d3c1011d0c209b2ca3982b3d7f5ae0337ca88 Mon Sep 17 00:00:00 2001 From: bae080311 Date: Tue, 31 Mar 2026 09:44:09 +0900 Subject: [PATCH 1/7] remove: console log --- code/renderers/react/src/componentManifest/reactDocgen/utils.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/code/renderers/react/src/componentManifest/reactDocgen/utils.ts b/code/renderers/react/src/componentManifest/reactDocgen/utils.ts index d6ec8e941fee..fde6cb7ad9df 100644 --- a/code/renderers/react/src/componentManifest/reactDocgen/utils.ts +++ b/code/renderers/react/src/componentManifest/reactDocgen/utils.ts @@ -130,7 +130,6 @@ export const getTsConfig = async () => { try { const ts = await import('typescript'); const tsconfigPath = ts.findConfigFile(process.cwd(), ts.sys.fileExists); - console.log({ tsconfigPath }); if (tsconfigPath === undefined) { return {}; } From f23c91ede53698af7ebe6ba43242e4af8821c139 Mon Sep 17 00:00:00 2001 From: bae080311 Date: Tue, 31 Mar 2026 09:46:58 +0900 Subject: [PATCH 2/7] feat: tsconfigPath type --- code/frameworks/react-vite/src/types.ts | 15 ++++++++++++++- code/presets/react-webpack/src/types.ts | 15 ++++++++++++++- .../src/componentManifest/getComponentImports.ts | 15 ++++++++++++++- 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/code/frameworks/react-vite/src/types.ts b/code/frameworks/react-vite/src/types.ts index 938139710843..8726278d9a47 100644 --- a/code/frameworks/react-vite/src/types.ts +++ b/code/frameworks/react-vite/src/types.ts @@ -59,7 +59,20 @@ type TypescriptOptions = TypescriptOptionsBase & { */ reactDocgen: 'react-docgen-typescript' | 'react-docgen' | false; /** Configures `@joshwooding/vite-plugin-react-docgen-typescript` */ - reactDocgenTypescriptOptions: Parameters[0]; + reactDocgenTypescriptOptions: Parameters[0] & { + /** + * Path to a custom tsconfig file for react-docgen-typescript. + * + * Useful in monorepo setups where the root tsconfig uses project references with empty + * `include`/`files` arrays. Point this to a tsconfig that explicitly includes your component + * source files so react-docgen-typescript can extract component documentation. + * + * The path is resolved relative to `process.cwd()`. + * + * @example './tsconfig.storybook.json' + */ + tsconfigPath?: string; + }; }; /** The interface for Storybook configuration in `main.ts` files. */ diff --git a/code/presets/react-webpack/src/types.ts b/code/presets/react-webpack/src/types.ts index 047c5ea59509..63b8c638995a 100644 --- a/code/presets/react-webpack/src/types.ts +++ b/code/presets/react-webpack/src/types.ts @@ -34,7 +34,20 @@ export type TypescriptOptions = TypescriptOptionsBase & { * @default * @see https://github.com/storybookjs/storybook/blob/next/code/builders/builder-webpack5/src/config/defaults.js#L4-L6 */ - reactDocgenTypescriptOptions: ReactDocgenTypescriptOptions; + reactDocgenTypescriptOptions: ReactDocgenTypescriptOptions & { + /** + * Path to a custom tsconfig file for react-docgen-typescript. + * + * Useful in monorepo setups where the root tsconfig uses project references with empty + * `include`/`files` arrays. Point this to a tsconfig that explicitly includes your component + * source files so react-docgen-typescript can extract component documentation. + * + * The path is resolved relative to `process.cwd()`. + * + * @example './tsconfig.storybook.json' + */ + tsconfigPath?: string; + }; }; export type StorybookConfig = diff --git a/code/renderers/react/src/componentManifest/getComponentImports.ts b/code/renderers/react/src/componentManifest/getComponentImports.ts index fd85a821f6dc..79bb47af51f8 100644 --- a/code/renderers/react/src/componentManifest/getComponentImports.ts +++ b/code/renderers/react/src/componentManifest/getComponentImports.ts @@ -22,7 +22,20 @@ export type DocgenEngine = 'react-docgen' | 'react-docgen-typescript' | 'react-c export interface TypescriptOptions extends TypescriptOptionsBase { reactDocgen: ReactDocgenConfig; - reactDocgenTypescriptOptions: ParserOptions; + reactDocgenTypescriptOptions: ParserOptions & { + /** + * Path to a custom tsconfig file for react-docgen-typescript. + * + * Useful in monorepo setups where the root tsconfig uses project references with empty + * `include`/`files` arrays. Point this to a tsconfig that explicitly includes your component + * source files so react-docgen-typescript can extract component documentation. + * + * The path is resolved relative to `process.cwd()`. + * + * @example './tsconfig.storybook.json' + */ + tsconfigPath?: string; + }; } export type { ComponentRef } from './types'; From a05e9fc63d3a621e0c2b3073dec2351f86ec56b8 Mon Sep 17 00:00:00 2001 From: bae080311 Date: Tue, 31 Mar 2026 09:47:46 +0900 Subject: [PATCH 3/7] docs(typescript): document tsconfigPath for monorepo setups --- .../main-config/main-config-typescript.mdx | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/docs/api/main-config/main-config-typescript.mdx b/docs/api/main-config/main-config-typescript.mdx index c23f8e693a77..afc0d551dc56 100644 --- a/docs/api/main-config/main-config-typescript.mdx +++ b/docs/api/main-config/main-config-typescript.mdx @@ -86,6 +86,35 @@ Options to pass to `fork-ts-checker-webpack-plugin`, if [enabled](#check). See [ {/* prettier-ignore-end */} + + ### `reactDocgenTypescriptOptions.tsconfigPath` + + Type: `string` + + Path to a custom tsconfig file for `react-docgen-typescript`. Useful in monorepo setups where the root `tsconfig.json` uses [project references](https://www.typescriptlang.org/docs/handbook/project-references.html) with empty `include`/`files` arrays, which causes `react-docgen-typescript` to find no source files and produce no component documentation. + + Point this to a tsconfig that explicitly lists the source files you want documented. The path is resolved relative to `process.cwd()`. + + ```ts + // .storybook/main.ts + const config: StorybookConfig = { + typescript: { + reactDocgen: 'react-docgen-typescript', + reactDocgenTypescriptOptions: { + tsconfigPath: './tsconfig.storybook.json', + }, + }, + }; + ``` + + For example, your `tsconfig.storybook.json` might look like: + + ```json + { + "extends": "./tsconfig.base.json", + "include": ["packages/*/src/**/*.ts", "packages/*/src/**/*.tsx"] + } + ``` ## `skipCompiler` From 936d25ebf071c2d84015561a5fcbfb79a85fdfac Mon Sep 17 00:00:00 2001 From: bae080311 Date: Tue, 31 Mar 2026 09:49:43 +0900 Subject: [PATCH 4/7] fix(typescript): enhance getParser to support user-defined tsconfigPath --- .../reactDocgenTypescript.ts | 34 ++++++++++++------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/code/renderers/react/src/componentManifest/reactDocgenTypescript.ts b/code/renderers/react/src/componentManifest/reactDocgenTypescript.ts index 8a9304fb16fe..b78ddbc49aa2 100644 --- a/code/renderers/react/src/componentManifest/reactDocgenTypescript.ts +++ b/code/renderers/react/src/componentManifest/reactDocgenTypescript.ts @@ -1,4 +1,4 @@ -import { dirname } from 'node:path'; +import { dirname, resolve } from 'node:path'; import { type ComponentDoc, @@ -180,7 +180,7 @@ export function invalidateParser() { cachedParserOptionsKey = undefined; } -async function getParser(userOptions?: ParserOptions) { +async function getParser(userOptions?: ParserOptions & { tsconfigPath?: string }) { const [typescript, reactDocgenTypescript] = await Promise.all([ loadTypeScript(), loadReactDocgenTypescript(), @@ -192,18 +192,23 @@ async function getParser(userOptions?: ParserOptions) { } if (!parser) { - const configPath = findTsconfigPath(process.cwd()); + const { tsconfigPath: userTsconfigPath, ...restUserOptions } = userOptions ?? {}; + const configPath = userTsconfigPath + ? resolve(process.cwd(), userTsconfigPath) + : findTsconfigPath(process.cwd()); cachedCompilerOptions = { noErrorTruncation: true, strict: true }; if (configPath) { - const { config } = typescript.readConfigFile(configPath, typescript.sys.readFile); - const parsed = typescript.parseJsonConfigFileContent( - config, - typescript.sys, - dirname(configPath) - ); - cachedCompilerOptions = { ...parsed.options, noErrorTruncation: true }; - cachedFileNames = parsed.fileNames; + const { config, error } = typescript.readConfigFile(configPath, typescript.sys.readFile); + if (!error) { + const parsed = typescript.parseJsonConfigFileContent( + config, + typescript.sys, + dirname(configPath) + ); + cachedCompilerOptions = { ...parsed.options, noErrorTruncation: true }; + cachedFileNames = parsed.fileNames; + } } const program = typescript.createProgram( @@ -217,7 +222,7 @@ async function getParser(userOptions?: ParserOptions) { const parserOptions: ParserOptions = { shouldExtractLiteralValuesFromEnum: true, shouldRemoveUndefinedFromOptional: true, - ...userOptions, + ...restUserOptions, // Always force savePropValueAsString so default values are in a consistent format savePropValueAsString: true, }; @@ -290,7 +295,10 @@ export function getReactDocgenTypescriptError( * `invalidateCache()`. The underlying TS program is a long-lived singleton. */ export const parseWithReactDocgenTypescript = asyncCache( - async (filePath: string, userOptions?: ParserOptions): Promise => { + async ( + filePath: string, + userOptions?: ParserOptions & { tsconfigPath?: string } + ): Promise => { const { program, fileParser, typescript } = await getParser(userOptions); const checker = program.getTypeChecker(); const sourceFile = program.getSourceFile(filePath); From baf0eb68132a989eafa6b4bcd10b3c6ffe7bb3b1 Mon Sep 17 00:00:00 2001 From: bae080311 Date: Tue, 31 Mar 2026 10:11:23 +0900 Subject: [PATCH 5/7] feat: error logging --- .../react/src/componentManifest/reactDocgenTypescript.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/code/renderers/react/src/componentManifest/reactDocgenTypescript.ts b/code/renderers/react/src/componentManifest/reactDocgenTypescript.ts index b78ddbc49aa2..70a1df6ac8a4 100644 --- a/code/renderers/react/src/componentManifest/reactDocgenTypescript.ts +++ b/code/renderers/react/src/componentManifest/reactDocgenTypescript.ts @@ -8,6 +8,8 @@ import { } from 'react-docgen-typescript'; import type ts from 'typescript'; +import { logger } from 'storybook/internal/node-logger'; + import { asyncCache, findTsconfigPath } from './utils'; export type ComponentDocWithExportName = ComponentDoc & { exportName: string }; @@ -208,6 +210,8 @@ async function getParser(userOptions?: ParserOptions & { tsconfigPath?: string } ); cachedCompilerOptions = { ...parsed.options, noErrorTruncation: true }; cachedFileNames = parsed.fileNames; + } else if (userTsconfigPath) { + logger.warn(`Failed to load tsconfig at "${configPath}": ${error.messageText}`); } } From 188c7c6094d1824cf491b83f69efef8499575c9d Mon Sep 17 00:00:00 2001 From: bae080311 Date: Tue, 31 Mar 2026 14:39:39 +0900 Subject: [PATCH 6/7] fix(typescript): improve error logging for tsconfig loading failures --- .../react/src/componentManifest/reactDocgenTypescript.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/renderers/react/src/componentManifest/reactDocgenTypescript.ts b/code/renderers/react/src/componentManifest/reactDocgenTypescript.ts index 70a1df6ac8a4..14d7537b580f 100644 --- a/code/renderers/react/src/componentManifest/reactDocgenTypescript.ts +++ b/code/renderers/react/src/componentManifest/reactDocgenTypescript.ts @@ -211,7 +211,7 @@ async function getParser(userOptions?: ParserOptions & { tsconfigPath?: string } cachedCompilerOptions = { ...parsed.options, noErrorTruncation: true }; cachedFileNames = parsed.fileNames; } else if (userTsconfigPath) { - logger.warn(`Failed to load tsconfig at "${configPath}": ${error.messageText}`); + logger.warn(`Failed to load tsconfig at "${configPath}": ${typescript.flattenDiagnosticMessageText(error.messageText, '\n')}`); } } From b6410095ea6590509cd7f3e084e47e0e95bc0759 Mon Sep 17 00:00:00 2001 From: bae080311 Date: Tue, 31 Mar 2026 23:22:44 +0900 Subject: [PATCH 7/7] Fix: Reset cachedFileNames in getParser function for improved TypeScript configuration handling --- .../react/src/componentManifest/reactDocgenTypescript.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/code/renderers/react/src/componentManifest/reactDocgenTypescript.ts b/code/renderers/react/src/componentManifest/reactDocgenTypescript.ts index 8d69b78cbe39..0e1cd7e05e53 100644 --- a/code/renderers/react/src/componentManifest/reactDocgenTypescript.ts +++ b/code/renderers/react/src/componentManifest/reactDocgenTypescript.ts @@ -199,6 +199,7 @@ async function getParser(userOptions?: ParserOptions & { tsconfigPath?: string } ? resolve(process.cwd(), userTsconfigPath) : findTsconfigPath(process.cwd()); cachedCompilerOptions = { noErrorTruncation: true, strict: true }; + cachedFileNames = undefined; if (configPath) {