Repository navigation
fix: port parcel-transformer-storybook to Storybook 11's csf-tools - #10811
Draft
kasperpeulen wants to merge 6 commits into
Draft
kasperpeulen wants to merge 6 commits into
kasperpeulen wants to merge 6 commits into
Conversation
Storybook 11 parses story files with OXC instead of Babel: CsfFile._ast
is gone and CsfFile._metaNode is an ESTree node, so the transformer
crashed on `csf._ast.program` and lost its source map.
Storybook now only loads, enriches and prints the story file. The Fast
Refresh and docgen edits run on the transformer's own @babel/parser
parse of that output, printed with @babel/generator and chained onto
Storybook's source map. Stories and meta are found at the offsets of
Storybook's nodes, which mean the same for Babel and ESTree nodes.
enrichCsf is async and is awaited now. Before, its story edits ran after
the file was printed, so stories never got docs.source.originalSource.
A legacy `Story.story = {parameters}` is hashed for Fast Refresh too,
as Storybook 11 no longer spreads it into `parameters`.
Same change as parcel-bundler/storybook's copy of this transformer.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…parser 7.24
This repo resolves @babel/parser to 7.24, which needs the
importAttributes plugin for `import … with {type: 'macro'}` in the S2
stories. Also resolve the new @babel/generator range to the existing
7.29.1 instead of adding a second copy.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…sf-tools editor Storybook 11 parses story files with OXC and edits them as text through `csf._editor`. Instead of parsing Storybook's output again with Babel, make the Fast Refresh and docgen edits on that editor, so there is one parse, one print and one source map, and code the edits do not touch keeps its mapping. - Story functions become components in place: a variable is renamed to `StoryN` and followed by a wrapper under its own name; a function declaration gets a wrapper before it; a `render` value is assigned to `StoryN` inside the expression (`wrapExpression`). - `_internalComponent` and `_hash` members go through `appendToList`; the CSF 2 assignments and `__docgenInfo` through `_appendStatement`. - The module is wrapped for Fast Refresh by removing `export` keywords and inserting the prelude, the `try` and the export list around the rest, as before. Drops @babel/parser, @babel/types and @babel/generator. Needs Storybook 11. Same change as parcel-bundler/storybook#6. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…a computed render key
Under HMR, a 'use client' directive stayed below the inserted prelude,
inside the `try`, where it is no longer a directive. A computed
`['render'](args) {}` method kept its brackets. Also print the docgen
target without parentheses when it is a member expression.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ools fixes made unneeded Storybook 11's editor now keeps a wrapper's suffix inside text written at the expression's end, lets several appendToList calls on one list add up, and has `update`, an overwrite that keeps what was written next to the span. So enrichCsf can run before this transformer's edits again; only the Fast Refresh wrapping still goes first, because statements appended later skip the ones it removes. A variable story is now renamed by rewriting its name alone. Same change as parcel-bundler/storybook#6. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Find the declarator of a story function with `parentOf` instead of indexing every top-level declaration, rewrite a `render` method into a function value that `addComponent` wraps like any other, and pass the editor to `wrapRefresh`. Every story export has annotations, so every story gets a `_hash`, and the guards for a missing one go. A `get render()` getter is left alone instead of being rewritten into invalid code, and a `render` method keeps `async` and `*`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2 of 9 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The transformer moves to Storybook 11's csf-tools, so the release that ships it needs Storybook 11.
Storybook 11 parses story files with oxc-parser instead of Babel:
storybook/internal/csf-toolsnow hands out ESTree nodes, andCsfFile._astis gone (storybookjs/storybook#36613, see its MIGRATION section).Today the transformer builds Babel nodes and pushes them into
csf._ast.program. On the canary, every story file throws under HMR:Without HMR the builds pass, but every asset loses its source map, and TypeScript stories lose
__docgenInfo.The transformer now edits the source text through
csf._editorand prints the file once withformatCsf. Code it does not touch keeps its formatting and its source map, story bodies included.@babel/parserand@babel/typesare no longer dependencies.For each story file it:
loadCsf(…).parse().enrichCsf, which adds each story'soriginalSourceand JSDoc description._hash; those with a story function also get_internalComponent.Button.__docgenInfo = {…}for the meta'scomponent.try. Then it prints the file with one source map.A story function becomes a component without moving its code:
becomes, wrapped here to fit:
A
renderfunction is named inside its expression.render: (args) => <Button {...args} />becomes:CSF 2 stories get
Primary._internalComponent = Story0;andPrimary._hash = "…";as statements. Object stories and the meta get them as members.Under HMR, the Babel version turned
export { type T as X }into$Export0 = T, which throws at runtime, and dropped theasyncof anasync render()method. It also skipped__docgenInfofor a'component'string key. The new version handles all three.Land it with the move to Storybook 11, once a Storybook 11 prerelease contains storybookjs/storybook#36613. The repo is on 10.3.5, where
yarn check-typesfails in this file because the csf-tools exports it uses do not exist yet. The transformer cannot support both, so move thestorybookranges from^10.0.0to that prerelease in the same change.Two behaviour changes are intended:
enrichCsfis async, and the transformer now awaits it. The Babel version did not, so its story edits landed after the file was printed. Stories now getparameters.docs.source.originalSourceand their JSDoc description.Story.story = {…}is hashed as a whole. Storybook 10 spread its members into the story's annotations, so itsargsandparameterswere hashed. Storybook 11 keeps it as onestoryannotation. Hashing all of it keeps Fast Refresh bailing out when it changes. A change to itsnameordecoratorsnow bails out too.The same change for the copy in parcel-bundler/storybook: parcel-bundler/storybook#6
No issue exists for this.
✅ Pull Request Checklist:
The transformer has no unit tests; the checks below stand in for them. Documentation and accessibility do not apply to build tooling.
📝 Test Instructions:
Everything ran on the canary
storybook@https://pkg.pr.new/storybook@93fc3eeand the matching@storybook/*packages, installed locally throughresolutions. Nothing here pins it: thestorybookranges still read^10.0.0.yarn build:storybookandyarn build:storybook-s2pass.yarn check-typesreports no errors in this package.yarn oxfmt --checkpasses on the file.I ran the transformer over the 455 story files of
.storybook,.storybook-s2,.chromaticand.chromatic-fc, with HMR on and off: 910 transforms. A stub docgen client gave every file docs. Each output ran with stubbed imports, and I compared it with the Babel transformer's output on Storybook 10. The comparison covers the exports, whether each export has a_hashand an_internalComponent, what each story renders through its component,__docgenInfo, and the refresh prelude and postlude. All 910 match.To try it, add the canary to
resolutionsforstorybookand the@storybook/*packages and runyarn install. Then runyarn start(port 9003) oryarn start:s2(port 6006), open a story and edit its render function. Fast Refresh should keep the component's state, as before. I did not run the dev server.On the canary,
yarn check-typesreports 729 errors elsewhere, from Storybook 11's own types. 711 come from the legacyStory.storyproperty (693 TS2339, 18 TS2559), 14 from stricter meta and args types, and 4 from@mdx-js/reactdeclaringJSXtwice. They belong to the Storybook 11 upgrade itself.🧢 Your Project:
Storybook (Storybook 11 csf-tools migration)
🤖 Generated with Claude Code