Skip to content

fix: don't treat functions with a rest parameter as components - #87

Open
brenelz wants to merge 1 commit into
solidjs:mainfrom
brenelz:fix/skip-rest-parameter-components
Open

brenelz wants to merge 1 commit into
solidjs:mainfrom
brenelz:fix/skip-rest-parameter-components

Conversation

@brenelz

@brenelz brenelz commented Sep 18, 2026

Copy link
Copy Markdown

Fixes solidjs/solid-vite-plugin#214

Problem

The Pascal-case heuristic wraps any capitalized top-level function with fewer than two declared parameters in the HMR component proxy. A rest parameter counts as one parameter, so a plain helper in a .jsx file like

export function GlobalTest(...arr) {
  console.log(...arr);
}

is wrapped in $$component. The runtime proxy is HMRComp(props) and forwards only its first argument, so GlobalTest(1, 2, 3) logs just 1 in dev. The same function in a .js file (never transformed) or in a production build (no refresh plugin) works, which is what the reporter saw.

Reproduced with the built plugin + runtime in Node: before this change the dev transform yields 1 for the function-declaration and arrow forms; after it yields 1 2 3 for both.

Fix

A component receives at most one argument (its props), so a function that declares a rest parameter can't be a component. isComponentishParams keeps the existing < 2 rule and also rejects a RestElement. It replaces the inline params.length < 2 check in all three wrapping paths: variable declarators, function declarations, and the hoisting path for export declarations.

An alternative would be to have the runtime proxy forward ...args, but that would still route plain functions through createMemo/untrack and register them as components. Skipping them at transform time matches how (a, b) functions are already handled.

Tests

Added a "with valid Component name and a rest parameter" case next to each existing ">1 params" case, for all five declaration shapes in all twenty suites (client/server × hydratable × bundler). The new snapshots show the function left untouched; no existing snapshot changed.

🤖 Generated with Claude Code

The Pascal-case heuristic wrapped any capitalized top-level function
with fewer than two declared parameters in the HMR component proxy.
A rest parameter counts as a single parameter, so a plain helper such
as `function GlobalTest(...arr)` in a `.jsx` file was proxied, and the
proxy (`HMRComp(props)`) forwards only its first argument. Calling
`GlobalTest(1, 2, 3)` in dev then received just `1`, while the same
function in a `.js` file or a production build worked.

A component receives at most one argument (its props), so a function
declaring a rest parameter can't be one. Skip it in all three wrapping
paths (function declarations, variable declarators, and hoisted
export declarations) and add snapshot tests for every declaration
shape across all bundler and mode suites.

Fixes solidjs/solid-vite-plugin#214

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
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.

Proxied Functions Do Not Handle Spreading

1 participant