Open lxsmnsyc opened 2 years ago
The particular use-case that brought this up was attempting to perform just-in-time server-side rendering in Deno with Solid.
Ideally, I'd like to use a proper dom-expressions
transform. Unfortunately:
eval()
.dom-expressions
expects a DOM.My next best bet was to try using hyper-dom-expressions
or lit-dom-expressions
for server-side rendering, then serve Babel-transformed files to the client to do partial hydration, but renderToString
and renderToStringAsync
are both logging empty strings:
/** @jsxImportSource https://esm.sh/solid-js@1.4.7/h */
import {
Document,
Element,
Node,
} from "https://deno.land/x/deno_dom/deno-dom-wasm.ts";
import { renderToString } from "https://esm.sh/solid-js/web/dist/server";
// @ts-ignore
globalThis.document = new Document();
// @ts-ignore
globalThis.Element = Element;
// @ts-ignore
globalThis.SVGElement = Element;
// @ts-ignore
globalThis.Node = Node;
const App = () => {
return <div>Hello world!</div>;
};
console.log(renderToString(() => <App />));
Given also that all three of dom-expressions
's runtime renderers apparently require DOM interfaces, I am a little confused on how server-side rendering is meant to be possible. I'm assuming this is just because the server builds of hyper-dom-expressions
or lit-dom-expressions
are missing?
Edit: replacing hyper-dom-expressions
with lit-dom-expressions
in the example above doesn't work either. It throws an error before the renderToString()
call is reached that I'm not entirely sure how to fix:
error: Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'querySelectorAll')
at m (https://esm.sh/v86/solid-js@1.4.7/deno/html.js:2:3734)
at v (https://esm.sh/v86/solid-js@1.4.7/deno/html.js:17:41)
at App (file:///home/dragonwocky/local/tmp/deno_solid/main.tsx:21:14)
at https://esm.sh/v86/solid-js@1.4.7/deno/solid-js.js:2:13610
at O (https://esm.sh/v86/solid-js@1.4.7/deno/solid-js.js:2:4892)
at Object.De [as createComponent] (https://esm.sh/v86/solid-js@1.4.7/deno/solid-js.js:2:13604)
at m (https://esm.sh/v86/solid-js@1.4.7/deno/h.js:2:1490)
at d (https://esm.sh/v86/solid-js@1.4.7/deno/h.js:2:290)
at P (https://esm.sh/v86/solid-js@1.4.7/deno/web/dist/server.js:2:9446)
at pe (https://esm.sh/v86/solid-js@1.4.7/deno/web/dist/server.js:2:5075)
SSR and even hydratable client both use different transforms than the standard client and leverage additional runtime behaviors. Hydration for a framework like Solid has been pretty tricky to figure out. I suspect the Tagged Template literals would be possible but not sure the HyperScript is.
I'm soon embarking into research to do more complex transformation for both the SSR and Hydration cases to support more performant approaches.
In any case good issue to track. But any runtime that cares about the combination of performance and ergonomics should consider supporting custom transforms or they will be leaving a ton on the table, both in server runtime perf and most importantly the ability for these solutions to do optimal hydration.
As the title says. Currently
hyper
andlit
only run on browser runtime, so if one were to use these on server-side, users aren't able to use SSR API fromdom-expressions