fix(compiler): extract "use server" function declarations nested in a function - #3369
Merged
Merged
Conversation
… function
The bubbling pre-pass turns every function declaration into
`const name = function name() {}` at the top of its block so the
transform only handles expression forms. Babel skipped the body of each
bubbled declaration (`tmp.skip()`), so a declaration nested inside
another function was never bubbled, never became an expression, and a
directive on it was silently ignored: the body shipped to the client
and ran there. The capture validator walks every function, so the same
declaration still had its captures rejected. One spelling produced a
compile error, the other a client-side body.
The bubbler now descends into each bubbled body, so nested declarations
are extracted like any other marked function, at any depth and inside
nested blocks. The const lands at the top of its block, so a use above
the declaration still resolves. Ids follow the binding path
(`outer.inner`). Only files that extract at least one function keep the
pass's output, so the extra bubbling never reaches a file without server
functions. No existing fixture contains a nested declaration, so the
frozen references are unchanged.
Co-authored-by: Claude via Cursor <noreply@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
🦋 Changeset detectedLatest commit: 882ad7f The changes in this PR will be included in the next version bump. This PR includes changesets to release 11 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Coverage Report for CI Build 34577398077Coverage remained the same at 71.842%Details
Uncovered ChangesNo uncovered changes found. Coverage RegressionsNo coverage regressions found. Coverage Stats
💛 - Coveralls |
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.
A
"use server"directive on a function declaration nested inside another function did nothing. The bubbling pre-pass turns declarations intoconst name = function name() {}so the transform only handles expression forms, but (matching Babel'stmp.skip()) it never descended into a bubbled body, so a nested declaration never became an expression and was never extracted. The body shipped to the client and ran there.Meanwhile the capture validator walks every function, so the same declaration did get its captures checked:
The bubbler now descends into each bubbled body, so nested declarations are extracted like any other marked function, at any depth and inside nested blocks. The
constlands at the top of its block, so a use above the declaration still resolves. Ids follow the binding path (outer.inner,outer.mid.inner).valid), so the extra bubbling never reaches a file without server functions.directives-nested-declarations.test.js(server and client shape, hoisting, depth, block nesting, capture rejection, unmarked declarations untouched).Surfaced while reviewing #3363/#3365.