Skip to content

Duplicate Code: previewAnnotations Pattern Repeated Across 5 Renderer Presets #34389

@github-actions

Description

@github-actions

Analysis of commit 0efef13

Assignee: @copilot

Summary

The previewAnnotations export function is nearly identical across 5 renderer preset files, differing only in the package name string. This is a clear copy-paste duplication that impacts maintainability and increases the risk of inconsistencies when the pattern needs to change.

Duplication Details

Pattern: Identical previewAnnotations factory logic across renderer presets

  • Severity: Medium

  • Occurrences: 5 instances

  • Locations:

    • code/renderers/html/src/preset.ts (lines 5–17)
    • code/renderers/preact/src/preset.ts (lines 5–19)
    • code/renderers/svelte/src/preset.ts (lines 5–19)
    • code/renderers/vue3/src/preset.ts (lines 5–17)
    • code/renderers/web-components/src/preset.ts (lines 5–22)
  • Code Sample (html renderer, representative of all 5):

    export const previewAnnotations: PresetProperty<'previewAnnotations'> = async (
      input = [],
      options
    ) => {
      const docsEnabled = Object.keys(await options.presets.apply('docs', {}, options)).length > 0;
      const result: string[] = [];
    
      return result
        .concat(input)
        .concat([fileURLToPath(import.meta.resolve('`@storybook/html`/entry-preview'))])
        .concat(
          docsEnabled ? [fileURLToPath(import.meta.resolve('`@storybook/html`/entry-preview-docs'))] : []
        );
    };

    The only difference across all 5 files is the package name (@storybook/html, @storybook/preact, @storybook/svelte, @storybook/vue3, @storybook/web-components). The docsEnabled check, result-building logic, and function signature are identical.

Impact Analysis

  • Maintainability: Any change to the docsEnabled check logic (e.g., adding another condition, changing how docs is detected) must be made in 5 separate files manually.
  • Bug Risk: A bug in one file may not be fixed in the others if developers don't know about the duplication.
  • Code Bloat: ~60 lines of functionally identical code spread across 5 packages.

Refactoring Recommendations

  1. Extract a shared factory helper

    • Create a utility in code/core/src/common/utils/ (e.g., createPreviewAnnotations.ts) or in a shared renderer utility:
      export function createPreviewAnnotations(packageName: string, extraEntries: string[] = []) {
        return async (input = [], options) => {
          const docsEnabled = Object.keys(await options.presets.apply('docs', {}, options)).length > 0;
          return ([] as string[])
            .concat(input)
            .concat(extraEntries.map(e => fileURLToPath(import.meta.resolve(e))))
            .concat([fileURLToPath(import.meta.resolve(`\$\{packageName}/entry-preview`))])
            .concat(docsEnabled ? [fileURLToPath(import.meta.resolve(`\$\{packageName}/entry-preview-docs`))] : []);
        };
      }
    • Each renderer then becomes a one-liner:
      export const previewAnnotations = createPreviewAnnotations('`@storybook/html`');
    • Estimated effort: 2–3 hours
    • Benefits: Single place to update the docs detection logic; consistent behavior across renderers
  2. Keep renderer-specific overrides (e.g., web-components adds entry-preview-argtypes, react has additional conditions) handled via the extraEntries parameter or a callback.

Implementation Checklist

  • Review duplication findings
  • Create shared createPreviewAnnotations factory
  • Update html, preact, svelte, vue3, web-components presets to use it
  • Confirm react preset (which has additional logic) either uses the factory with extensions or stays separate
  • Update tests if any exist for these presets
  • Verify no functionality broken

Analysis Metadata

  • Analyzed Files: 5 renderer preset files
  • Detection Method: Semantic code analysis + direct file comparison
  • Commit: 0efef13
  • Analysis Date: 2026-03-29

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 changelogtech debt

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions