From f8d1a35ace6e1f0c0349ab26c7b9b97b2df7a2a8 Mon Sep 17 00:00:00 2001 From: Ryan Carniato Date: Tue, 5 Oct 2021 09:20:51 -0700 Subject: [PATCH] Add hydration to Solid renderer (#1479) * feat: add hydration to Solid renderer * fix: intersection observer, move script to the end --- packages/renderers/renderer-solid/client.js | 11 +++-------- packages/renderers/renderer-solid/index.js | 7 ++++--- packages/renderers/renderer-solid/server.js | 17 ++++++++--------- .../renderers/renderer-solid/static-html.js | 4 ++-- 4 files changed, 17 insertions(+), 22 deletions(-) diff --git a/packages/renderers/renderer-solid/client.js b/packages/renderers/renderer-solid/client.js index 815f3d8e5..f4cdb4ead 100644 --- a/packages/renderers/renderer-solid/client.js +++ b/packages/renderers/renderer-solid/client.js @@ -1,16 +1,11 @@ -import { createComponent } from 'solid-js'; -import { render } from 'solid-js/web'; +import { hydrate, createComponent } from 'solid-js/web'; export default (element) => (Component, props, childHTML) => { - // Solid's `render` does not replace the element's children. - // Deleting the root's children is necessary before calling `render`. - element.replaceChildren(); - const children = document.createElement('astro-fragment'); children.innerHTML = childHTML; - // Using Solid's `render` method ensures that a `root` is created + // Using Solid's `hydrate` method ensures that a `root` is created // in order to properly handle reactivity. It also handles // components that are not native HTML elements. - render(() => createComponent(Component, { ...props, children }), element); + hydrate(() => createComponent(Component, { ...props, children }), element); }; diff --git a/packages/renderers/renderer-solid/index.js b/packages/renderers/renderer-solid/index.js index 9224c069d..cafd5e43a 100644 --- a/packages/renderers/renderer-solid/index.js +++ b/packages/renderers/renderer-solid/index.js @@ -2,17 +2,18 @@ export default { name: '@astrojs/renderer-solid', client: './client', server: './server', - knownEntrypoints: ['solid-js', 'solid-js/web'], - external: ['solid-js/web/dist/server.js', 'solid-js/dist/server.js', 'babel-preset-solid'], + knownEntrypoints: ['solid-js', 'solid-js/web', 'solid-js/store'], + external: ['solid-js/web/dist/server.js', 'solid-js/store/dist/server.js', 'solid-js/dist/server.js', 'babel-preset-solid'], jsxImportSource: 'solid-js', jsxTransformOptions: async ({ isSSR }) => { const [{ default: solid }] = await Promise.all([import('babel-preset-solid')]); const options = { - presets: [solid({}, { generate: isSSR ? 'ssr' : 'dom' })], + presets: [solid({}, { generate: isSSR ? 'ssr' : 'dom', hydratable: true })], }; if (isSSR) { options.alias = { + 'solid-js/store': 'solid-js/store/dist/server.js', 'solid-js/web': 'solid-js/web/dist/server.js', 'solid-js': 'solid-js/dist/server.js', }; diff --git a/packages/renderers/renderer-solid/server.js b/packages/renderers/renderer-solid/server.js index 86506ca45..1d99ac378 100644 --- a/packages/renderers/renderer-solid/server.js +++ b/packages/renderers/renderer-solid/server.js @@ -1,24 +1,23 @@ -import { createComponent } from 'solid-js'; -import { renderToStringAsync, ssr } from 'solid-js/web/dist/server.js'; +import { renderToString, ssr, createComponent } from 'solid-js/web/dist/server.js'; -async function check(Component, props, children) { +function check(Component, props, children) { if (typeof Component !== 'function') return false; - const { html } = await renderToStaticMarkup(Component, props, children); + const { html } = renderToStaticMarkup(Component, props, children); return typeof html === 'string'; } -async function renderToStaticMarkup(Component, props, children) { - const html = await renderToStringAsync( - () => () => +function renderToStaticMarkup(Component, props, children) { + const html = renderToString( + () => createComponent(Component, { ...props, // In Solid SSR mode, `ssr` creates the expected structure for `children`. // In Solid client mode, `ssr` is just a stub. - children: ssr([`${children}`]), + children: ssr(`${children}`), }) ); - return { html }; + return { html: html + `` }; } export default { diff --git a/packages/renderers/renderer-solid/static-html.js b/packages/renderers/renderer-solid/static-html.js index 953416c49..fdbd56250 100644 --- a/packages/renderers/renderer-solid/static-html.js +++ b/packages/renderers/renderer-solid/static-html.js @@ -1,4 +1,4 @@ -import { createComponent } from 'solid-js'; +import { ssr } from 'solid-js/web/dist/server.js'; /** * Astro passes `children` as a string of HTML, so we need @@ -6,7 +6,7 @@ import { createComponent } from 'solid-js'; */ const StaticHtml = ({ innerHTML }) => { if (!innerHTML) return null; - return () => createComponent('astro-fragment', { innerHTML }); + return ssr(`${innerHTML }`); }; export default StaticHtml;