Summary
When an SSR application uses $ServerOnly on a component's root JSX element, the initial render and hydration succeed, but the first HMR update throws and leaves stale DOM.
babel-plugin-jsx-dom-expressions@0.40.10 now defaults omitServerOnlyTemplates to true. During a client HMR re-evaluation, Solid Refresh calls the component outside the initial hydration pass, but the compiled component only calls getNextElement() and has no retained template.
Because vite-plugin-solid already determines needHmr, could it default omitServerOnlyTemplates to false for client transforms while HMR is active? An explicit user setting should presumably continue to win.
Reproduction
https://github.com/birkskyum/repro-solid-server-only-hmr
git clone https://github.com/birkskyum/repro-solid-server-only-hmr.git
cd repro-solid-server-only-hmr
pnpm install
pnpm dev
- Open http://localhost:4174.
- Change
edit me! in src/App.tsx and save.
Actual
The DOM does not update, and the HMR evaluation throws:
TypeError: template is not a function
at getNextElement (.../solid-js/web/dist/dev.js)
at _$getNextElement (src/App.tsx)
at HMRComp.createMemo.name [as fn] (@solid-refresh)
Expected
The component hot-updates normally.
Control / proposed direction
The exact same edit succeeds when the compiler option is set explicitly:
solid({
ssr: true,
solid: { omitServerOnlyTemplates: false },
})
This appears to be needed only for the client transform when HMR is enabled; server and production transforms can keep omitting the template.
Versions
solid-js@1.9.15
vite-plugin-solid@2.11.14
babel-preset-solid@1.9.15
babel-plugin-jsx-dom-expressions@0.40.10
vite@8.2.1
Downstream report: solidjs/solid-start#1930
Relevant dom-expressions change: ryansolid/dom-expressions@3774c79
Summary
When an SSR application uses
$ServerOnlyon a component's root JSX element, the initial render and hydration succeed, but the first HMR update throws and leaves stale DOM.babel-plugin-jsx-dom-expressions@0.40.10now defaultsomitServerOnlyTemplatestotrue. During a client HMR re-evaluation, Solid Refresh calls the component outside the initial hydration pass, but the compiled component only callsgetNextElement()and has no retained template.Because
vite-plugin-solidalready determinesneedHmr, could it defaultomitServerOnlyTemplatestofalsefor client transforms while HMR is active? An explicit user setting should presumably continue to win.Reproduction
https://github.com/birkskyum/repro-solid-server-only-hmr
git clone https://github.com/birkskyum/repro-solid-server-only-hmr.git cd repro-solid-server-only-hmr pnpm install pnpm devedit me!insrc/App.tsxand save.Actual
The DOM does not update, and the HMR evaluation throws:
Expected
The component hot-updates normally.
Control / proposed direction
The exact same edit succeeds when the compiler option is set explicitly:
This appears to be needed only for the client transform when HMR is enabled; server and production transforms can keep omitting the template.
Versions
solid-js@1.9.15vite-plugin-solid@2.11.14babel-preset-solid@1.9.15babel-plugin-jsx-dom-expressions@0.40.10vite@8.2.1Downstream report: solidjs/solid-start#1930
Relevant dom-expressions change: ryansolid/dom-expressions@3774c79