Skip to content

Core: Fix Yarn PnP support #31968

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Jul 8, 2025
Merged

Core: Fix Yarn PnP support #31968

merged 12 commits into from
Jul 8, 2025

Conversation

JReinhold
Copy link
Contributor

@JReinhold JReinhold commented Jul 7, 2025

What I did

This PR makes some changes to the resolution logic to keep supporting Yarn PnP.
It also introduces a Yarn PnP "Test Storybook", that we can use to ensure it is supported. In CI it builds the Storybook and runs the Vitest tests.

Checklist for Contributors

Testing

The changes in this PR are covered in the following automated tests:

  • stories
  • unit tests
  • integration tests
  • end-to-end tests

Manual testing

This section is mandatory for all contributions. If you believe no manual test is necessary, please state so explicitly. Thanks!

Documentation

  • Add or update documentation reflecting your changes
  • If you are deprecating/removing a feature, make sure to update
    MIGRATION.MD

Checklist for Maintainers

  • When this PR is ready for testing, make sure to add ci:normal, ci:merged or ci:daily GH label to it to run a specific set of sandboxes. The particular set of sandboxes can be found in code/lib/cli-storybook/src/sandbox-templates.ts

  • Make 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 PR does not have a canary release associated. You can request a canary release of this pull request by mentioning the @storybookjs/core team here.

core team members can create a canary release here or locally with gh workflow run --repo storybookjs/storybook canary-release-pr.yml --field pr=<PR_NUMBER>

Greptile Summary

Improves Yarn Plug'n'Play (PnP) support in Storybook by refactoring module resolution logic and adding comprehensive testing infrastructure.

  • Modified code/core/src/common/js-package-manager/Yarn2Proxy.ts to properly handle PnP API loading and error handling
  • Simplified builder resolution in code/core/src/core-server/utils/get-builders.ts by removing custom path handling
  • Added dedicated Yarn PnP test Storybook with complete Vite+React setup for CI verification
  • Implemented CircleCI job 'test-yarn-pnp' to ensure PnP compatibility across all workflows
  • Updated preset loading in code/core/src/common/presets.ts to use more reliable module resolution for PnP environments

Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR adds comprehensive Yarn Plug’n’Play support by configuring test sandboxes, streamlining module resolution in core utilities, and integrating a new CI job.

  • Added a Vitest-based workspace configuration for the Yarn PnP sandbox
  • Simplified builder lookup by removing configDir dependencies and switching to direct module imports
  • Updated addon and package resolution to leverage import.meta.resolve and built-in pnpapi
  • Introduced a dedicated test-yarn-pnp job in CircleCI workflows

Reviewed Changes

Copilot reviewed 34 out of 55 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
test-storybooks/yarn-pnp/vitest.workspace.ts New Vitest workspace setup using storybookTest for PnP sandbox
code/core/src/core-server/utils/get-builders.ts Removed configDir argument from getPreviewBuilder and updated callers
code/core/src/common/presets.ts Replaced resolvePathSync with importMetaResolve + fileURLToPath in addon resolution
code/core/src/common/js-package-manager/Yarn2Proxy.ts Switched to dynamic import of built-in pnpapi and adjusted error code check
.circleci/config.yml Added test-yarn-pnp job to multiple workflows for end-to-end PnP validation
Comments suppressed due to low confidence (1)

code/core/src/core-server/utils/get-builders.ts:1

  • [nitpick] Public functions getManagerBuilder, getPreviewBuilder, and getBuilders are core parts of the builder resolution API. Adding JSDoc comments would improve clarity on expected inputs, outputs, and error cases.
import { MissingBuilderError } from 'storybook/internal/server-errors';

Copy link

nx-cloud bot commented Jul 7, 2025

View your CI Pipeline Execution ↗ for commit d4ec962

Command Status Duration Result
nx run-many -t build --parallel=3 ✅ Succeeded 1m 1s View ↗

☁️ Nx Cloud last updated this comment at 2025-07-08 09:23:59 UTC

const pnpApi = await import(pnpapiPath);
try {
// @ts-expect-error TS doesn't know about the built-in Yarn PnP API
const { default: pnpApi } = await import('pnpapi');
Copy link
Contributor

Choose a reason for hiding this comment

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

This will break many storybook cli usages, which respawns commands using npx.

I thought that this was the site of the issues I found in automigrations, before I realised you weren't importing the pnpapi module - but it now will be.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ah that's a good point, thank you! I reverted the changes and added a comment explaining this to the next person.

I'd say that the proper fix would be to find all those places where we spawn sub processes of Storybook, and ensure that they do it with the right package manager command, but that's not my concern here.

This feels like a fragile solution, surely loading the pnp loader manually is not officially supported and will break at some point.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think all of the implementations would be a lot simpler if you could guarantee they were running under the original runtime; you could just then import the package.json directly, or at the very least require.resolve it and read it using native fs (which would be already patched in yarn berry).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

True. I don't have the overview of all the places where we spin up a new process, but I know that in the dispatcher code in the core CLI, it's a trade off with performance and size. Essentially by making npm run storybook automigrate run npx @storybook/cli automigrate, it means that the core storybook package only have to contain the workflows that are used daily - dev, build - instead of installing and parsing the workflows that are executed very rarely like upgrade and automigrate. I think that is the right trade off.

Copy link
Contributor

Choose a reason for hiding this comment

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

I agree to a point - one pain point is it makes debugging a bit more tricky as you have to ensure you bypass all the respawns.

My point is that if we respawn using the correct runtime, then we can drop some of the complexity here without sacrificing those advantages.

I'd be happy to attempt a PR to that end, if you think it's worth it.

Copy link
Contributor Author

@JReinhold JReinhold Jul 8, 2025

Choose a reason for hiding this comment

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

My point is that if we respawn using the correct runtime

Can you elaborate on what you mean by this? What would the change be?

Copy link
Contributor

@mrginglymus mrginglymus Jul 8, 2025

Choose a reason for hiding this comment

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

Replace this line:

command = ['npx', '--yes', `@storybook/cli@${versions.storybook}`, ...args];

with something like

command = JsPackageManagerFactory.getPackageManager({}).getRemoteRunCommand(`@storybook/cli@${versions.storybook}`, args)'

though, now I come to think about it, I'm not sure whether a yarn dlx process would have access to the pnp runtime of the cwd...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ah yes then I agree with you, on both counts. 😅

Feel free to open a PR, but probably use sb10/esm-only as a base, as that has changed quite a bit.

Copy link
Contributor

Choose a reason for hiding this comment

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

fyi early draft - #31989 some degree of yak shaving happened (:

@storybook-pr-benchmarking
Copy link

storybook-pr-benchmarking bot commented Jul 7, 2025

Package Benchmarks

Commit: d4ec962, ran on 8 July 2025 at 09:12:53 UTC

No significant changes detected, all good. 👏

@JReinhold JReinhold marked this pull request as ready for review July 8, 2025 10:23
@JReinhold JReinhold requested a review from ndelangen July 8, 2025 10:23
Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

37 files reviewed, 28 comments
Edit PR Review Bot Settings | Greptile

@JReinhold JReinhold merged commit 4889efd into sb10/esm-only Jul 8, 2025
52 of 55 checks passed
@JReinhold JReinhold deleted the jeppe/fix-yarn-pnp branch July 8, 2025 10:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants