Skip to content

CLI: Narrow CSF Factories Subpath Imports#34889

Closed
alan747271363-art wants to merge 3 commits into
storybookjs:nextfrom
alan747271363-art:codex/narrow-csf-factory-imports
Closed

CLI: Narrow CSF Factories Subpath Imports#34889
alan747271363-art wants to merge 3 commits into
storybookjs:nextfrom
alan747271363-art:codex/narrow-csf-factory-imports

Conversation

@alan747271363-art
Copy link
Copy Markdown

@alan747271363-art alan747271363-art commented May 23, 2026

What changed

  • Replace the broad CSF factories imports map fallback (#*) with a scoped #storybook/* import target based on the resolved Storybook config directory.
  • Generate and update story preview imports to use #storybook/<preview filename> with the preview file extension when subpath imports are selected.
  • Add regression coverage for the imports map target, story codemod output, and the new preview import path shape.

Fixes #32935.

Testing

  • node .yarn\releases\yarn-4.10.3.cjs install --immutable
  • node .yarn\releases\yarn-4.10.3.cjs nx run-many -t compile -p core cli
  • $env:CI='true'; node .yarn\releases\yarn-4.10.3.cjs vitest run code/lib/cli-storybook/src/codemod/helpers/story-to-csf-factory.test.ts code/lib/cli-storybook/src/codemod/csf-factories.test.ts code/core/src/csf-tools/CsfFile.test.ts
  • node .yarn\releases\yarn-4.10.3.cjs exec oxfmt --check code/lib/cli-storybook/src/codemod/csf-factories.ts code/lib/cli-storybook/src/codemod/csf-factories.test.ts code/lib/cli-storybook/src/codemod/helpers/story-to-csf-factory.ts code/lib/cli-storybook/src/codemod/helpers/story-to-csf-factory.test.ts code/core/src/csf-tools/CsfFile.test.ts
  • node .yarn\releases\yarn-4.10.3.cjs nx run-many -t check -p core cli

Manual testing

Not run. This changes the CSF factories automigration path generation and package.json imports map logic, covered by targeted unit tests.

Summary by CodeRabbit

  • New Features

    • CLI now respects an explicit config directory when computing and applying Storybook subpath imports.
    • Preview path examples and handling support explicit file extensions (e.g., .ts) and scoped import forms.
    • package.json imports map is updated automatically and removes legacy mappings when detected.
  • Tests

    • Expanded coverage for subpath import generation, preview-path variants (including .ts), imports-map updates and refresh behavior.

Review Change Stack

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 23, 2026

Fails
🚫

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

Generated by 🚫 dangerJS against 9ef51b0

@alan747271363-art

This comment was marked as low quality.

@alan747271363-art

This comment was marked as low quality.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 23, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: bc3365d1-5361-4ab5-b418-8c4ce0fa1b84

📥 Commits

Reviewing files that changed from the base of the PR and between a9d86fe and 9ef51b0.

📒 Files selected for processing (1)
  • code/lib/cli-storybook/src/codemod/csf-factories.test.ts

📝 Walkthrough

Walkthrough

Adds POSIX path helpers to compute #storybook/* subpath import targets from a configurable configDir, updates story-to-csf transformation to accept configDir and use computed preview import strings (including file extensions), and modifies CSF factories to compute/update #storybook/* in package.json imports (removing legacy #*) and pass resolved config paths into the codemod; tests were added/updated.

Changes

Scoped Storybook subpath imports with file extensions

Layer / File(s) Summary
Path computation helpers
code/lib/cli-storybook/src/codemod/helpers/story-to-csf-factory.ts, code/lib/cli-storybook/src/codemod/csf-factories.ts
Introduces POSIX normalization and helpers (toPosixPath, getSubpathPreviewImport, getStorybookSubpathImportTarget) to compute normalized #storybook/* subpath import targets from config directories and detect legacy shapes.
Story transformation with configDir
code/lib/cli-storybook/src/codemod/helpers/story-to-csf-factory.ts, code/lib/cli-storybook/src/codemod/helpers/story-to-csf-factory.test.ts, code/core/src/csf-tools/CsfFile.test.ts
storyToCsfFactory accepts optional configDir, computes preview import paths via helper (replacing the hardcoded preview path), updates inline doc/example text, and tests validate scoped preview imports (including .ts extension) and legacy-to-scoped migration.
CSF factories orchestration and tests
code/lib/cli-storybook/src/codemod/csf-factories.ts, code/lib/cli-storybook/src/codemod/csf-factories.test.ts
runStoriesCodemod accepts/forwards configDir, resolves preview/config paths relative to package operationDir, computes and writes #storybook/* into package.json imports when needed, removes legacy #* entries when matching legacy shape, and includes tests for target computation, imports-map updates, and path normalization.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • storybookjs/storybook#33039: Updates CSF preview detection and broader “storybook” import source handling related to preview imports.
  • storybookjs/storybook#32610: Modifies csf-factories and story-to-csf-factory subpath preview imports; this PR's configDir-based scoped import generation extends that work.

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.

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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@code/lib/cli-storybook/src/codemod/csf-factories.ts`:
- Around line 123-126: The code currently forwards the raw configDir into
getStorybookSubpathImportTarget (and the similar helper at the later call) which
lets relative configDir be resolved from process.cwd(); normalize configDir
against the package operation dir first by resolving it with
packageManager.primaryPackageJson.operationDir (e.g., use
path.resolve(operationDir, configDir) or equivalent) and pass that resolved path
into getStorybookSubpathImportTarget and the other helper call so both
targets/imports are computed relative to the package's operationDir.
- Around line 130-133: The current logic only sets imports['`#storybook/`*'] when
it is missing, leaving stale mappings in package.json; change the code so
imports['`#storybook/`*'] is assigned storybookImportTarget unconditionally (or at
least when its value !== storybookImportTarget) and set shouldWritePackageJson =
true when you overwrite it, using the existing imports['`#storybook/`*'] and
shouldWritePackageJson symbols to detect and replace stale mappings so package
resolution is updated on reruns.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 12ddf8a9-47b0-4821-966d-9c3bf235b549

📥 Commits

Reviewing files that changed from the base of the PR and between 1411339 and ca3effe.

📒 Files selected for processing (5)
  • code/core/src/csf-tools/CsfFile.test.ts
  • code/lib/cli-storybook/src/codemod/csf-factories.test.ts
  • code/lib/cli-storybook/src/codemod/csf-factories.ts
  • code/lib/cli-storybook/src/codemod/helpers/story-to-csf-factory.test.ts
  • code/lib/cli-storybook/src/codemod/helpers/story-to-csf-factory.ts

Comment thread code/lib/cli-storybook/src/codemod/csf-factories.ts
Comment thread code/lib/cli-storybook/src/codemod/csf-factories.ts Outdated
@alan747271363-art

This comment was marked as low quality.

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/lib/cli-storybook/src/codemod/csf-factories.test.ts (1)

14-26: 💤 Low value

Mocks should use spy: true with behaviors defined in beforeEach.

As per coding guidelines, Vitest mocks should use vi.mock() with the spy: true option and implement mock behaviors in beforeEach blocks rather than inline factory implementations.

♻️ Suggested refactor for guideline compliance
-vi.mock('../automigrate/codemod.ts', () => ({
-  runCodemod: vi.fn(),
-}));
-vi.mock('./helpers/story-to-csf-factory.ts', () => ({
-  storyToCsfFactory: vi.fn(async () => 'transformed story'),
-}));
-vi.mock('./helpers/config-to-csf-factory.ts', () => ({
-  configToCsfFactory: vi.fn(async () => 'transformed config'),
-}));
-vi.mock('storybook/internal/common', async (importOriginal) => ({
-  ...(await importOriginal<typeof import('storybook/internal/common')>()),
-  syncStorybookAddons: vi.fn(),
-}));
+vi.mock('../automigrate/codemod.ts', { spy: true });
+vi.mock('./helpers/story-to-csf-factory.ts', { spy: true });
+vi.mock('./helpers/config-to-csf-factory.ts', { spy: true });
+vi.mock('storybook/internal/common', { spy: true });
+
+import { configToCsfFactory } from './helpers/config-to-csf-factory.ts';
+import { syncStorybookAddons } from 'storybook/internal/common';

 beforeEach(() => {
   vi.clearAllMocks();
   process.env.IN_STORYBOOK_SANDBOX = '1';
+  vi.mocked(runCodemod).mockResolvedValue(undefined);
+  vi.mocked(storyToCsfFactory).mockResolvedValue('transformed story');
+  vi.mocked(configToCsfFactory).mockResolvedValue('transformed config');
+  vi.mocked(syncStorybookAddons).mockResolvedValue(undefined);
 });

As per coding guidelines: "Use vi.mock() with the spy: true option for all package and file mocks in Vitest tests" and "Implement mock behaviors in beforeEach blocks in Vitest tests".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@code/lib/cli-storybook/src/codemod/csf-factories.test.ts` around lines 14 -
26, Change the inline vi.mock factory implementations to use spy: true and move
the mock behaviors into a beforeEach setup: call vi.mock(...) with { spy: true }
for the modules currently mocked (the module exporting runCodemod,
'./helpers/story-to-csf-factory' exporting storyToCsfFactory,
'./helpers/config-to-csf-factory' exporting configToCsfFactory, and
'storybook/internal/common' exposing syncStorybookAddons), then in beforeEach
set expectations with the mocked functions (e.g.,
vi.mocked(runCodemod).mockImplementation / .mockResolvedValue,
vi.mocked(storyToCsfFactory).mockResolvedValue('transformed story'),
vi.mocked(configToCsfFactory).mockResolvedValue('transformed config'), and
vi.mocked(syncStorybookAddons).mockImplementation) so mocks follow the spy
pattern and behaviors are initialized per-test.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@code/lib/cli-storybook/src/codemod/csf-factories.test.ts`:
- Around line 14-26: Change the inline vi.mock factory implementations to use
spy: true and move the mock behaviors into a beforeEach setup: call vi.mock(...)
with { spy: true } for the modules currently mocked (the module exporting
runCodemod, './helpers/story-to-csf-factory' exporting storyToCsfFactory,
'./helpers/config-to-csf-factory' exporting configToCsfFactory, and
'storybook/internal/common' exposing syncStorybookAddons), then in beforeEach
set expectations with the mocked functions (e.g.,
vi.mocked(runCodemod).mockImplementation / .mockResolvedValue,
vi.mocked(storyToCsfFactory).mockResolvedValue('transformed story'),
vi.mocked(configToCsfFactory).mockResolvedValue('transformed config'), and
vi.mocked(syncStorybookAddons).mockImplementation) so mocks follow the spy
pattern and behaviors are initialized per-test.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 559a3ffb-cf46-425b-8592-a9cfae7f1af3

📥 Commits

Reviewing files that changed from the base of the PR and between ca3effe and a9d86fe.

📒 Files selected for processing (2)
  • code/lib/cli-storybook/src/codemod/csf-factories.test.ts
  • code/lib/cli-storybook/src/codemod/csf-factories.ts

@alan747271363-art

This comment was marked as low quality.

@valentinpalkovic
Copy link
Copy Markdown
Contributor

Hi @alan747271363-art,

Due to a recent high volume of unreviewed AI-generated PRs, we are requesting verification and proof that the implemented fix actually works. Please provide a simple GIF/Video or image of how the fix works, optimally with before-and-after comparisons.

Thank you for your understanding!

@alan747271363-art

This comment was marked as low quality.

@valentinpalkovic
Copy link
Copy Markdown
Contributor

Closing due to purely AI-generated content.

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

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

[Bug]: CSF-Factories migration: Do not use fallback array for subpath imports

2 participants