Addon-Vitest: Skip postinstall setup when configured#33712
Addon-Vitest: Skip postinstall setup when configured#33712valentinpalkovic merged 3 commits intonextfrom
Conversation
|
View your CI Pipeline Execution ↗ for commit bdf0cf9
☁️ Nx Cloud last updated this comment at |
a03ec3f to
2b12f5b
Compare
📝 WalkthroughWalkthroughAdds AST-based detection (isConfigAlreadySetup) to the Vitest addon's postinstall flow, updates postinstall to reuse existing setup files or skip changes when config already contains the Storybook test plugin, adds unit tests, and removes a specific exported error class from core server errors. Changes
Sequence DiagramsequenceDiagram
actor User
participant PostInstall as Postinstall Handler
participant ConfigDetector as isConfigAlreadySetup
participant AST as AST Parser/Traverse
participant VitestConfig as Vitest Config File
participant SetupFile as .storybook/vitest.setup.ts
User->>PostInstall: Run postinstall
PostInstall->>PostInstall: Detect workspace/root config presence
PostInstall->>ConfigDetector: isConfigAlreadySetup(configPath, content)
ConfigDetector->>VitestConfig: Read config content
ConfigDetector->>AST: Parse & traverse AST
AST-->>ConfigDetector: Plugin import/usage found?
ConfigDetector-->>PostInstall: true/false
alt true (already configured)
PostInstall->>PostInstall: Log reuse/skip and exit
else false (not configured)
PostInstall->>SetupFile: Check for existing setup file
alt exists
PostInstall->>PostInstall: Reuse file and log
else
PostInstall->>SetupFile: Create setup file
SetupFile-->>PostInstall: File created
end
PostInstall->>VitestConfig: Insert plugin in config (if root config)
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
✨ Finishing touches
Tip 🧪 Unit Test Generation v2 is now available!We have significantly improved our unit test generation capabilities. To enable: Add this to your reviews:
finishing_touches:
unit_tests:
enabled: trueTry it out by using the Have feedback? Share your thoughts on our Discord thread! Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
code/addons/vitest/src/postinstall.ts (1)
241-287: Avoid returning early so downstream setup still runs.
The early return skips a11y automigration and the final success/error messaging for workspace users, while the root-config path continues. Consider logging and then continuing (or guarding only the update block).🛠️ Suggested fix
- if (alreadyConfigured) { - logger.step( - CLI_COLORS.success('Vitest for Storybook is already properly configured. Skipping setup.') - ); - return; - } - - const workspaceTemplate = await loadTemplate('vitest.workspace.template.ts', { - EXTENDS_WORKSPACE: viteConfigFile - ? relative(dirname(vitestWorkspaceFile), viteConfigFile) - : '', - CONFIG_DIR: options.configDir, - SETUP_FILE: relative(dirname(vitestWorkspaceFile), existingSetupFile ?? vitestSetupFile), - }).then((t) => t.replace(`\n 'ROOT_CONFIG',`, '').replace(/\s+extends: '',/, '')); - const source = babelParse(workspaceTemplate); - const target = babelParse(workspaceFileContent); - - const updated = updateWorkspaceFile(source, target); - if (updated) { - logger.step(`Updating your Vitest workspace file...`); - - logger.log(`${vitestWorkspaceFile}`); - - const formattedContent = await formatFileContent(vitestWorkspaceFile, generate(target).code); - await writeFile(vitestWorkspaceFile, formattedContent); - } else { - logger.error( - dedent` - Could not update existing Vitest workspace file: - ${vitestWorkspaceFile} - - I was able to configure most of the addon but could not safely extend - your existing workspace file automatically, you must do it yourself. - - Please refer to the documentation to complete the setup manually: - https://storybook.js.org/docs/next/${DOCUMENTATION_LINK}#manual-setup-advanced - ` - ); - errors.push( - new AddonVitestPostinstallWorkspaceUpdateError({ filePath: vitestWorkspaceFile }) - ); - } + if (alreadyConfigured) { + logger.step( + CLI_COLORS.success('Vitest for Storybook is already properly configured. Skipping setup.') + ); + } else { + const workspaceTemplate = await loadTemplate('vitest.workspace.template.ts', { + EXTENDS_WORKSPACE: viteConfigFile + ? relative(dirname(vitestWorkspaceFile), viteConfigFile) + : '', + CONFIG_DIR: options.configDir, + SETUP_FILE: relative(dirname(vitestWorkspaceFile), existingSetupFile ?? vitestSetupFile), + }).then((t) => t.replace(`\n 'ROOT_CONFIG',`, '').replace(/\s+extends: '',/, '')); + const source = babelParse(workspaceTemplate); + const target = babelParse(workspaceFileContent); + + const updated = updateWorkspaceFile(source, target); + if (updated) { + logger.step(`Updating your Vitest workspace file...`); + + logger.log(`${vitestWorkspaceFile}`); + + const formattedContent = await formatFileContent( + vitestWorkspaceFile, + generate(target).code + ); + await writeFile(vitestWorkspaceFile, formattedContent); + } else { + logger.error( + dedent` + Could not update existing Vitest workspace file: + ${vitestWorkspaceFile} + + I was able to configure most of the addon but could not safely extend + your existing workspace file automatically, you must do it yourself. + + Please refer to the documentation to complete the setup manually: + https://storybook.js.org/docs/next/${DOCUMENTATION_LINK}#manual-setup-advanced + ` + ); + errors.push( + new AddonVitestPostinstallWorkspaceUpdateError({ filePath: vitestWorkspaceFile }) + ); + } + }
🤖 Fix all issues with AI agents
In `@code/addons/vitest/src/postinstall.ts`:
- Around line 427-473: The current isConfigAlreadySetup only checks for a plugin
reference and returns true even if setupFiles is missing; update
isConfigAlreadySetup to require both the plugin reference and that the config
object defines a non-empty setupFiles entry. Keep the existing AST traversal
that collects pluginIdentifiers (ImportDeclaration) and detects plugin usage
(CallExpression), then add a traversal that finds the exported config object
(e.g., ExportDefaultDeclaration with an ObjectExpression and/or
AssignmentExpression to module.exports) and looks for a setupFiles property
whose value is an ArrayExpression with at least one element or a non-empty
string; only return true when pluginReferenced is true AND setupFiles is
present/valid. Ensure you update references inside isConfigAlreadySetup
(pluginIdentifiers, pluginReferenced, and the AST traversals) rather than
changing callers.
🧹 Nitpick comments (1)
code/addons/vitest/src/postinstall.test.ts (1)
31-49: Add a negative case for missingsetupFiles.
OnceisConfigAlreadySetupenforces setupFiles presence, a test where the plugin exists but setupFiles is missing will lock in the smart-skip behavior.As per coding guidelines: Cover all branches, conditions, edge cases, error paths, and different input variations in unit tests.✅ Proposed test
it('returns false when storybookTest plugin is not used', () => { @@ expect(isConfigAlreadySetup('/project/vitest.config.ts', config, setupPath)).toBe(false); }); + + it('returns false when setupFiles is missing even if the plugin is present', () => { + const config = ` + import { defineConfig } from 'vitest/config'; + import { storybookTest } from '@storybook/addon-vitest/vitest-plugin'; + + export default defineConfig({ + test: { + projects: [ + { + extends: true, + plugins: [storybookTest({ configDir: '.storybook' })], + }, + ], + }, + }); + `; + + expect(isConfigAlreadySetup('/project/vitest.config.ts', config, setupPath)).toBe(false); + }); });
ghengeveld
left a comment
There was a problem hiding this comment.
Nice improvement. Only some minor remarks (feel free to ignore).
| function isStorybookTestPluginSource(value: string) { | ||
| return value === STORYBOOK_TEST_PLUGIN_SOURCE; | ||
| } |
There was a problem hiding this comment.
Seems a bit unnecessary to have a function for such a trivial thing?
| logger.step( | ||
| CLI_COLORS.success('Vitest for Storybook is already properly configured. Skipping setup.') | ||
| ); |
There was a problem hiding this comment.
Could reuse the message above.
…-existing-configs Addon-Vitest: Skip postinstall setup when configured (cherry picked from commit 0da33fb)
Closes #33695
What I did
This PR refactors the
@storybook/addon-vitestpostinstall script to be more idempotent and user-friendly. Instead of failing when it encounters existing configurations or setup files, the script now intelligently detects existing setups and avoids redundant modifications.Checklist for Contributors
Testing
The changes in this PR are covered in the following automated tests:
Manual testing
Caution
This section is mandatory for all contributions. If you believe no manual test is necessary, please state so explicitly. Thanks!
Documentation
MIGRATION.MD
Checklist for Maintainers
When this PR is ready for testing, make sure to add
ci:normal,ci:mergedorci:dailyGH label to it to run a specific set of sandboxes. The particular set of sandboxes can be found incode/lib/cli-storybook/src/sandbox-templates.tsMake sure this PR contains one of the labels below:
Available labels
bug: Internal changes that fixes incorrect behavior.maintenance: User-facing maintenance tasks.dependencies: Upgrading (sometimes downgrading) dependencies.build: Internal-facing build tooling & test updates. Will not show up in release changelog.cleanup: Minor cleanup style change. Will not show up in release changelog.documentation: Documentation only changes. Will not show up in release changelog.feature request: Introducing a new feature.BREAKING CHANGE: Changes that break compatibility in some way with current major version.other: Changes that don't fit in the above categories.🦋 Canary release
This pull request has been released as version
0.0.0-pr-33712-sha-bdf0cf9e. Try it out in a new sandbox by runningnpx storybook@0.0.0-pr-33712-sha-bdf0cf9e sandboxor in an existing project withnpx storybook@0.0.0-pr-33712-sha-bdf0cf9e upgrade.More information
0.0.0-pr-33712-sha-bdf0cf9evalentin/addon-vitest-skip-existing-configsbdf0cf9e1769756816)To request a new release of this pull request, mention the
@storybookjs/coreteam.core team members can create a new canary release here or locally with
gh workflow run --repo storybookjs/storybook publish.yml --field pr=33712Summary by CodeRabbit
New Features
Tests
Chores
✏️ Tip: You can customize this high-level summary in your review settings.