Skip to content

Fix react-docgen-typescript with Vite-style project references tsconfig#34416

Open
kasperpeulen wants to merge 1 commit into
nextfrom
kasper/fix-rdt-project-references
Open

Fix react-docgen-typescript with Vite-style project references tsconfig#34416
kasperpeulen wants to merge 1 commit into
nextfrom
kasper/fix-rdt-project-references

Conversation

@kasperpeulen
Copy link
Copy Markdown
Member

@kasperpeulen kasperpeulen commented Mar 31, 2026

Summary

Closes #34414

  • Modern Vite projects use a tsconfig.json with only project references (files: [], references: [...]), where the actual compiler options and file include patterns live in tsconfig.app.json
  • The manifest's react-docgen-typescript parser was finding this root tsconfig but getting zero source files from it, causing component prop extraction to silently return empty results
  • When the parsed config yields no file names and has project references, we now follow the references to find the first config that includes source files

Test plan

  • Added unit tests for parseWithReactDocgenTypescript covering basic props, union types, default values, JSON serialization round-trip, multi-component matching, prop filtering
  • Added test that reproduces the exact Vite-style project references scenario (tsconfig.json with files: [] and references pointing to tsconfig.app.json)
  • All 268 existing componentManifest tests still pass

Summary by CodeRabbit

  • Tests

    • Added comprehensive test suite for React component documentation parsing, validating output structure, prop extraction, descriptions, and JSON serialization.
  • Improvements

    • Enhanced TypeScript configuration loading to support Vite-style project references, allowing proper resolution when configurations use references instead of direct file lists.

Modern Vite projects use a tsconfig.json with only project references
(`files: [], references: [...]`), where the actual compiler options and
file include patterns live in tsconfig.app.json. The manifest's RDT
parser was finding this root tsconfig but getting zero source files from
it, causing component prop extraction to silently fail.

When the parsed config yields no file names and has project references,
we now follow the references to find the first config that includes
source files.

Closes #34414
@github-actions
Copy link
Copy Markdown
Contributor

Fails
🚫

PR is not labeled with one of: ["cleanup","BREAKING CHANGE","feature request","bug","documentation","maintenance","build","dependencies"]

🚫

PR is not labeled with one of: ["ci:normal","ci:merged","ci:daily","ci:docs"]

🚫 PR title must be in the format of "Area: Summary", With both Area and Summary starting with a capital letter Good examples: - "Docs: Describe Canvas Doc Block" - "Svelte: Support Svelte v4" Bad examples: - "add new api docs" - "fix: Svelte 4 support" - "Vue: improve docs"

Generated by 🚫 dangerJS against 3df558b

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 31, 2026

📝 Walkthrough

Walkthrough

Adds a comprehensive test suite for React Docgen Typescript integration and enhances TypeScript config resolution to support Vite-style project references. Tests validate parsing of component documentation, JSON serializability, and multi-export matching using temporary TypeScript projects. Implementation adds fallback logic to load referenced tsconfig files when the primary config yields no fileNames.

Changes

Cohort / File(s) Summary
React Docgen Typescript Parsing
code/renderers/react/src/componentManifest/reactDocgenTypescript.ts, code/renderers/react/src/componentManifest/reactDocgenTypescript.test.ts
Enhanced TypeScript config loading with fallback support for Vite-style project references (when files: [] with references array). Added comprehensive test suite validating parseWithReactDocgenTypescript and matchComponentDoc against real temporary TypeScript projects, including JSON serializability, prop filtering, and JSDoc parsing.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

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

208-233: Good implementation for handling Vite-style project references.

The logic correctly follows TypeScript project references when the root tsconfig yields no file names. The handling of both directory references (./tsconfig.app) and direct JSON file references (./tsconfig.app.json) aligns with TypeScript's behavior.

One consideration: if all referenced configs also yield zero file names, the original empty parsed is used silently. This is likely fine since it degrades gracefully to the existing behavior, but adding a debug log could help troubleshoot complex setups.

💡 Optional: Add debug logging when following references
       // Vite-style project references: tsconfig.json has { files: [], references: [...] }
       // which yields 0 file names. Follow the references to find a config with source files.
       if (parsed.fileNames.length === 0 && Array.isArray(config.references)) {
+        logger.debug('Root tsconfig has no files, following project references...');
         for (const ref of config.references as { path: string }[]) {
           const refPath = resolve(dirname(configPath), ref.path);
           // A reference path can point to a directory (meaning <dir>/tsconfig.json)
           // or directly to a config file.
           const refConfigPath = refPath.endsWith('.json')
             ? refPath
             : resolve(refPath, 'tsconfig.json');
           const refResult = typescript.readConfigFile(refConfigPath, typescript.sys.readFile);
           if (refResult.error || !refResult.config) {
             continue;
           }

           const refParsed = typescript.parseJsonConfigFileContent(
             refResult.config,
             typescript.sys,
             dirname(refConfigPath)
           );
           if (refParsed.fileNames.length > 0) {
+            logger.debug(`Using referenced tsconfig: ${refConfigPath}`);
             parsed = refParsed;
             break;
           }
         }
       }
🤖 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 208 - 233, Add a debug log when following TypeScript project references
and when no referenced config yields fileNames so investigators can trace why
parsed.fileNames remained empty: inside the block that checks parsed.fileNames
=== 0 && Array.isArray(config.references) (and when iterating refs using
refPath/refConfigPath), log the ref being attempted and the result of
typescript.readConfigFile and typescript.parseJsonConfigFileContent (use the
same logger used elsewhere or a temporary debug logger) and, after the loop, log
a warning if parsed.fileNames is still 0 to indicate fallback to the original
parsed; refer to symbols parsed, config.references, configPath, refConfigPath,
typescript.readConfigFile and typescript.parseJsonConfigFileContent to locate
where to add these logs.
code/renderers/react/src/componentManifest/reactDocgenTypescript.test.ts (1)

16-24: Consider cleaning up temp directories after tests.

The createTempProject helper creates temp directories but they're never cleaned up. While the OS will eventually clean them, explicit cleanup prevents accumulation during long test runs or CI.

♻️ Proposed cleanup enhancement
+import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from 'node:fs';
-import { mkdtempSync, mkdirSync, writeFileSync } from 'node:fs';

+const tempDirs: string[] = [];
+
 // Create a temporary directory with a tsconfig and component files
 // to exercise RDT against real files on disk (memfs can't be used with RDT).
 function createTempProject(files: Record<string, string>) {
   const dir = mkdtempSync(path.join(tmpdir(), 'sb-rdt-test-'));
+  tempDirs.push(dir);
   for (const [name, content] of Object.entries(files)) {
     const filePath = path.join(dir, name);
     mkdirSync(path.dirname(filePath), { recursive: true });
     writeFileSync(filePath, content, 'utf-8');
   }
   return dir;
 }

 afterEach(() => {
   invalidateParser();
   invalidateCache();
   vi.restoreAllMocks();
+  // Clean up temp directories
+  for (const dir of tempDirs) {
+    rmSync(dir, { recursive: true, force: true });
+  }
+  tempDirs.length = 0;
 });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@code/renderers/react/src/componentManifest/reactDocgenTypescript.test.ts`
around lines 16 - 24, The helper createTempProject currently creates temp
directories but never removes them; modify it to return both the temp directory
path and a cleanup function (or push created dirs into a shared array) so tests
can explicitly delete the directory after running; implement cleanup by removing
the directory recursively (e.g., using fs.rmSync or rimraf) and call that
cleanup from the test teardown (afterEach/afterAll) to avoid accumulating temp
files. Ensure references to createTempProject in tests are updated to call the
cleanup function or rely on the shared-tracking cleanup in teardown.
🤖 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.test.ts`:
- Around line 16-24: The helper createTempProject currently creates temp
directories but never removes them; modify it to return both the temp directory
path and a cleanup function (or push created dirs into a shared array) so tests
can explicitly delete the directory after running; implement cleanup by removing
the directory recursively (e.g., using fs.rmSync or rimraf) and call that
cleanup from the test teardown (afterEach/afterAll) to avoid accumulating temp
files. Ensure references to createTempProject in tests are updated to call the
cleanup function or rely on the shared-tracking cleanup in teardown.

In `@code/renderers/react/src/componentManifest/reactDocgenTypescript.ts`:
- Around line 208-233: Add a debug log when following TypeScript project
references and when no referenced config yields fileNames so investigators can
trace why parsed.fileNames remained empty: inside the block that checks
parsed.fileNames === 0 && Array.isArray(config.references) (and when iterating
refs using refPath/refConfigPath), log the ref being attempted and the result of
typescript.readConfigFile and typescript.parseJsonConfigFileContent (use the
same logger used elsewhere or a temporary debug logger) and, after the loop, log
a warning if parsed.fileNames is still 0 to indicate fallback to the original
parsed; refer to symbols parsed, config.references, configPath, refConfigPath,
typescript.readConfigFile and typescript.parseJsonConfigFileContent to locate
where to add these logs.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d5073267-5ce0-489e-98f3-01b73500eefe

📥 Commits

Reviewing files that changed from the base of the PR and between d748443 and 3df558b.

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

dirname(refConfigPath)
);
if (refParsed.fileNames.length > 0) {
parsed = refParsed;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This would only include the first reference isn't it ?
What if the first referenced tsconfig doesn't include app components ?
like:

{
  "files": [],
  "references": [
    { "path": "./tsconfig.node.json" },
    { "path": "./tsconfig.app.json" }
  ]
}

@github-actions github-actions Bot added the Stale label Apr 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: React-component-typescript docgen broken in new Vite project

2 participants