Skip to content

Duplicate Code: docgen-resolver.ts Identical in react-vite and react-webpack #34442

@github-actions

Description

@github-actions

Analysis of commit a00ff8a

Assignee: @copilot

Summary

defaultLookupModule and its supporting code (RESOLVE_EXTENSIONS, ReactDocgenResolveError) are duplicated verbatim across two separate packages. The files explicitly acknowledge this with "watch out" comments warning maintainers to update both files manually — a fragile maintenance pattern.

Duplication Details

Pattern: Identical defaultLookupModule implementation

  • Severity: High
  • Occurrences: 2 near-identical files (82 lines each, diff = 1 comment line)
  • Locations:
    • code/frameworks/react-vite/src/plugins/docgen-resolver.ts (lines 1–82)
    • code/presets/react-webpack/src/loaders/docgen-resolver.ts (lines 1–82)
  • Verified diff: only line 17 differs — each file references the other in its warning comment

Code Sample (identical in both files, excluding the cross-reference comment):

export class ReactDocgenResolveError extends Error {
  readonly code = 'MODULE_NOT_FOUND';
  constructor(filename: string) {
    super(`'\$\{filename}' was ignored by react-docgen.`);
  }
}

export const RESOLVE_EXTENSIONS = [
  '.js', '.cts', '.mts', '.ctsx', '.mtsx',
  '.ts', '.tsx', '.mjs', '.cjs', '.mts', '.cts', '.jsx',
];

export function defaultLookupModule(filename: string, basedir: string): string {
  const resolveOptions = {
    basedir,
    extensions: RESOLVE_EXTENSIONS,
    includeCoreModules: false,
  };
  try {
    return resolve.sync(filename, resolveOptions);
  } catch (error) {
    // ... JS-to-TS fallback logic (identical in both files)
  }
}
```

**Warning comment present in both files**:
```
/* watch out: when updating this code, also update the code in code/presets/react-webpack/src/loaders/docgen-resolver.ts */

Impact Analysis

  • Maintainability: Any bug fix or enhancement to defaultLookupModule must be applied to two files manually. The "watch out" comment is the only safeguard — easy to miss.
  • Bug Risk: High. Divergence has already begun: react-vite uses supportedExtensions from storybook/internal/common while react-webpack defines its own RESOLVE_EXTENSIONS array inline.
  • Code Bloat: ~164 lines of duplicated logic that should be ~82 lines in a shared location.

Refactoring Recommendations

  1. Extract to a shared utility

    • Create: code/core/src/common/utils/docgen-resolver.ts (or inside react-docgen tools)
    • Export ReactDocgenResolveError, RESOLVE_EXTENSIONS, and defaultLookupModule
    • Import from both react-vite and react-webpack packages
    • Estimated effort: ~1 hour
  2. Unify RESOLVE_EXTENSIONS

    • The react-vite version uses supportedExtensions from storybook/internal/common; the react-webpack version has a hardcoded list. Consolidate to use the shared constant.

Implementation Checklist

  • Review duplication findings
  • Create shared utility at code/core/src/common/utils/docgen-resolver.ts
  • Update react-vite to import from shared utility
  • Update react-webpack to import from shared utility
  • Remove "watch out" warning comments
  • Verify no functionality broken
  • Run relevant tests

Analysis Metadata

  • Analyzed Files: 3 files (react-vite/docgen-resolver.ts, react-webpack/docgen-resolver.ts, react/componentManifest/reactDocgen/docgenResolver.ts)
  • Detection Method: Serena semantic code analysis + diff verification
  • Commit: a00ff8a
  • Analysis Date: 2026-04-02

Generated by Duplicate Code Detector ·

To install this agentic workflow, run

gh aw add github/gh-aw/.github/workflows/duplicate-code-detector.md@852cb06ad52958b402ed982b69957ffc57ca0619

Metadata

Metadata

Assignees

No one assigned

    Labels

    cleanupMinor cleanup style change that won't show up in release changelogmaintenanceUser-facing maintenance taskstech debt

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions