@rsbuild/plugin-solid — SSR with multi-environment builds requires manual workarounds
#7537
DEliasVCruz
started this conversation in
Ideas
Replies: 1 comment
-
|
Thanks for the detailed write-up! This makes sense to me. I agree we can consider two improvements:
A PR would be welcome ❤️ |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Hey! I've been building a SolidJS SSR app using Rsbuild's multi-environment setup (web + node targets) and ran into some friction with
@rsbuild/plugin-solidthat I wanted to bring up.The setup
Pretty standard SSR architecture — two Rsbuild environments:
The client entry calls
hydrate(), the server entry callsrenderToStream().What went wrong
My app kept crashing with
ReferenceError: window is not defined. Which was odd considering I was following what was in the solid plugin documentationhttps://rsbuild.rs/plugins/list/plugin-solid; and my implementation was not doing anything crazy. So I asked claude to lend me a hand.I found out that out of the box,
pluginSolid()applies the samebabel-preset-solidoptions to both environments. For SSR you needgenerate: "ssr"on the node side andgenerate: "dom"on the web side, but there's no way to express that with a single plugin call.The bigger issue was
@solidjs/routerand@solidjs/meta. These packages ship a"solid"export condition that points to raw JSX source (dist/index.jsx), and a"default"that points to pre-compiled client-only JS. For SSR, you need the JSX source sobabel-preset-solidcan compile it withgenerate: "ssr". But the plugin doesn't add"solid"to rspack'sresolve.conditionNames, so the pre-compiled client code gets bundled into the server and it's what leads to a crash.Claude being the code generation hungry beast that it is initally wrote for me a ~50 line custom rsbuild plugin to handle this (manually aliasing packages, adding extra babel rules, walking the rspack config to patch presets). It worked but was ugly and fragile.
The workaround I landed on
After giving it more thought and asking claude to go through the source code of the plugin solid. It turns out Rsbuild's per-environment config handles this cleanly once you know the right knobs:
One gotcha:
conditionNamesreplaces rspack's defaults entirely, so you must include"node"— otherwisesolid-jsitself resolves to its browser bundle and you get the samewindow is not definedcrash.Why I think this could live in the plugin
For comparison,
vite-plugin-solidhandles both of these automatically — it adds the"solid"export condition and detects SSR mode to switchgenerate. Users don't have to think about it.@rsbuild/plugin-solidcould do the same:"solid"toconditionNames(this is safe — packages without the condition just fall through to the next one)"node", setgenerate: "ssr"inbabel-preset-solidautomaticallyThis would make the "just works" experience match Vite for SolidJS SSR, which is a common use case now that Rsbuild has the multi-environment API.
I realize SSR with Solid on Rsbuild is probably a niche setup right now, but the fix is small and the current DX is pretty rough — you either have to know about
conditionNamesand per-environment plugins (which aren't documented for Solid), or write a custom plugin to patch the babel config at runtime.Happy to put together a PR if this sounds reasonable. Would love to hear if others have hit this or if there's a better approach I'm missing.
Beta Was this translation helpful? Give feedback.
All reactions