Skip to content

fix(ssr): rewrite imported binding used as computed key in defaulted destructuring param - #23233

Open
webbertakken wants to merge 2 commits into
vitejs:mainfrom
webbertakken:fix/ssr-computed-key-defaulted-param
Open

fix(ssr): rewrite imported binding used as computed key in defaulted destructuring param#23233
webbertakken wants to merge 2 commits into
vitejs:mainfrom
webbertakken:fix/ssr-computed-key-defaulted-param

Conversation

@webbertakken

Copy link
Copy Markdown

Description

Under SSR, an imported binding used as a computed key in a destructured parameter that has a default value (function f({ [KEY]: v } = {}) {}) was not rewritten to the import namespace, throwing ReferenceError: KEY is not defined at runtime (via ssrLoadModule, vite-node, and Vitest).

Fixes #23232.

Root cause

A destructured parameter with a default is an AssignmentPattern, so it is walked by the generic param walker in ssrTransform rather than by handlePattern. That walker only skipped non-computed property keys (isStaticPropertyKey), so a computed key referencing an imported binding was registered as a local scope variable via setScope. The later rewrite pass then treated it as a local and skipped the import rewrite, leaving a bare identifier.

handlePattern (used for non-defaulted ObjectPattern/ArrayPattern params) already ignores computed keys, which is why the same code without a default value worked.

Fix

Skip any property key that is not the bound value (both static and computed), mirroring handlePattern:

if (parent?.type === 'Property' && parent.key === child && parent.value !== child) {
  return
}

Shorthand bindings ({ x } = {}, where key === value) remain scoped; computed keys stay rewritable.

Tests

Added packages/vite/src/node/ssr/__tests__/ssrTransform.spec.ts case verifying the computed key is rewritten in both the parameter and the function body. The full ssrTransform spec passes (76 tests). Also verified end-to-end with a standalone createServer().ssrLoadModule(...) repro: throws before this change, returns the expected object after.

Note: this contribution was prepared with AI assistance; I have verified the reasoning, the fix, and the tests.

…destructuring param

A destructured parameter with a default value (`{ [KEY]: v } = {}`) is an AssignmentPattern, so it is walked by the generic param walker instead of handlePattern. That walker only skipped non-computed property keys (isStaticPropertyKey), so a computed key referencing an imported binding was registered as a local scope variable, causing the SSR import-rewrite to be skipped and throwing `ReferenceError` at runtime.

Skip any property key that is not the bound value (static or computed), mirroring handlePattern, so computed keys stay rewritable while shorthand bindings remain scoped.

Fixes vitejs#23232
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SSR transform: imported binding used as a computed key in a defaulted destructured parameter is not rewritten (ReferenceError)

1 participant