feat(rsc): bind accessed member expression value for use server closure#1172
Merged
feat(rsc): bind accessed member expression value for use server closure#1172
use server closure#1172Conversation
…ey and ExportSpecifier
- `{ [expr]: b }` — `expr` is now correctly treated as a reference (was
incorrectly treated as a binding), `b` correctly as a binding
- `ExportSpecifier` — `local` is now correctly treated as a reference,
`exported` as a non-reference (was treating both as references)
- Add test case for computed destructuring key captured from outer scope
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Codex <noreply@openai.com>
Co-authored-by: Codex <noreply@openai.com>
There was a problem hiding this comment.
Pull request overview
This PR enhances the RSC server-action hoisting transform so closures that reference member-access chains (e.g. config.api.key) bind only the accessed subtree instead of serializing/binding the full root object. This reduces RSC payload size and avoids runtime serialization failures when the root contains non-serializable values.
Changes:
- Extend scope analysis to track the “outermost bindable” reference node per identifier (identifier vs. non-computed member-expression chain, with callee trimming).
- Update hoist binding to synthesize partial object literals per root identifier and bind those (while keeping the hoisted function parameter as the root name).
- Add/refresh fixtures + snapshots and add design notes; update formatter ignore patterns for new
*.snap.jsfiles.
Reviewed changes
Copilot reviewed 31 out of 31 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/plugin-rsc/src/transforms/utils.ts | Adds a shared DefaultMap helper (moved out of tests). |
| packages/plugin-rsc/src/transforms/scope.ts | Tracks member-expression chains per reference (referenceToNode) and applies callee trimming. |
| packages/plugin-rsc/src/transforms/scope.test.ts | Updates scope serializer to optionally display the tracked reference node; uses shared DefaultMap. |
| packages/plugin-rsc/src/transforms/hoist.ts | Changes bind-var extraction to synthesize partial-object bind expressions for member chains. |
| packages/plugin-rsc/src/transforms/hoist.test.ts | Adds fixture-based snapshot testing for hoist output and updates/clarifies some existing edge-case comments. |
| packages/plugin-rsc/src/transforms/fixtures/scope/reference-node/member-chain.js | New fixture for plain member chain reference-node tracking. |
| packages/plugin-rsc/src/transforms/fixtures/scope/reference-node/member-chain.js.snap.json | Snapshot for plain member chain reference-node tracking. |
| packages/plugin-rsc/src/transforms/fixtures/scope/reference-node/member-chain-optional.js | New fixture for optional-chain boundary behavior. |
| packages/plugin-rsc/src/transforms/fixtures/scope/reference-node/member-chain-optional.js.snap.json | Snapshot for optional-chain boundary behavior. |
| packages/plugin-rsc/src/transforms/fixtures/scope/reference-node/member-chain-computed.js | New fixture for computed-access boundary behavior. |
| packages/plugin-rsc/src/transforms/fixtures/scope/reference-node/member-chain-computed.js.snap.json | Snapshot for computed-access boundary behavior. |
| packages/plugin-rsc/src/transforms/fixtures/scope/reference-node/member-chain-callee.js | New fixture for callee-trimming behavior. |
| packages/plugin-rsc/src/transforms/fixtures/scope/reference-node/member-chain-callee.js.snap.json | Snapshot for callee-trimming behavior. |
| packages/plugin-rsc/src/transforms/fixtures/hoist/member-chain.js | New hoist fixture for partial-object binding of member chains. |
| packages/plugin-rsc/src/transforms/fixtures/hoist/member-chain.js.snap.js | Snapshot for member-chain partial-object binding. |
| packages/plugin-rsc/src/transforms/fixtures/hoist/member-chain-siblings.js | New hoist fixture for merging sibling paths under one root. |
| packages/plugin-rsc/src/transforms/fixtures/hoist/member-chain-siblings.js.snap.js | Snapshot for sibling-path merge binding. |
| packages/plugin-rsc/src/transforms/fixtures/hoist/member-chain-root.js | New hoist fixture where direct root access forces binding the whole root. |
| packages/plugin-rsc/src/transforms/fixtures/hoist/member-chain-root.js.snap.js | Snapshot for root-access override binding. |
| packages/plugin-rsc/src/transforms/fixtures/hoist/member-chain-optional.js | New hoist fixture for optional-chain conservative fallback behavior. |
| packages/plugin-rsc/src/transforms/fixtures/hoist/member-chain-optional.js.snap.js | Snapshot for optional-chain fallback behavior. |
| packages/plugin-rsc/src/transforms/fixtures/hoist/member-chain-dedupe.js | New hoist fixture for prefix dedupe behavior. |
| packages/plugin-rsc/src/transforms/fixtures/hoist/member-chain-dedupe.js.snap.js | Snapshot for prefix-dedupe binding result. |
| packages/plugin-rsc/src/transforms/fixtures/hoist/member-chain-computed.js | New hoist fixture for computed-access conservative fallback behavior. |
| packages/plugin-rsc/src/transforms/fixtures/hoist/member-chain-computed.js.snap.js | Snapshot for computed-access fallback behavior. |
| packages/plugin-rsc/src/transforms/fixtures/hoist/member-chain-callee.js | New hoist fixture verifying callee trimming preserves receiver capture. |
| packages/plugin-rsc/src/transforms/fixtures/hoist/member-chain-callee.js.snap.js | Snapshot for callee-trimming hoist output. |
| packages/plugin-rsc/src/transforms/fixtures/hoist/member-chain-unsupported.js | New hoist fixture covering multiple unsupported patterns. |
| packages/plugin-rsc/src/transforms/fixtures/hoist/member-chain-unsupported.js.snap.js | Snapshot for unsupported-pattern binding behavior. |
| packages/plugin-rsc/docs/notes/2026-04-05-rsc-member-chain-binding-plan.md | Design note documenting the chosen approach and rationale. |
| packages/plugin-rsc/docs/notes/2026-04-05-member-chain-optional-computed-follow-up.md | Follow-up note outlining optional/computed access support considerations. |
| .oxfmtrc.json | Expands ignore pattern to cover *.snap.* (including new *.snap.js). |
Comments suppressed due to low confidence (1)
packages/plugin-rsc/src/transforms/scope.test.ts:10
- Typo in comment: “snaphsot” → “snapshot”.
// - use single markdown as snaphsot? (cf. review-scope-fixtures.ts)
describe('fixtures', () => {
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Codex <noreply@openai.com>
Base automatically changed from
test-rsc-add-test-for-use-server-binding-and-shadowing
to
main
April 6, 2026 05:25
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.
Description
use servervariable binding #1170TODO