From 8cb56c1b78a20549d2c1878f590cf5a4b4bc2f1f Mon Sep 17 00:00:00 2001 From: "lili.21" Date: Thu, 3 Nov 2022 15:17:57 +0800 Subject: [PATCH] support streaming ssr --- .../cloudflare-workers/app/entry.client.tsx | 22 ++++++++- .../cloudflare-workers/app/entry.server.tsx | 45 ++++++++++++++----- templates/cloudflare-workers/package.json | 8 ++-- templates/cloudflare-workers/wrangler.toml | 1 + 4 files changed, 58 insertions(+), 18 deletions(-) diff --git a/templates/cloudflare-workers/app/entry.client.tsx b/templates/cloudflare-workers/app/entry.client.tsx index 3eec1fd0a02..f1fed31afcc 100644 --- a/templates/cloudflare-workers/app/entry.client.tsx +++ b/templates/cloudflare-workers/app/entry.client.tsx @@ -1,4 +1,22 @@ import { RemixBrowser } from "@remix-run/react"; -import { hydrate } from "react-dom"; +import { startTransition, StrictMode } from "react"; +import { hydrateRoot } from "react-dom/client"; -hydrate(, document); +function hydrate() { + startTransition(() => { + hydrateRoot( + document, + + + + ); + }); +} + +if (window.requestIdleCallback) { + window.requestIdleCallback(hydrate); +} else { + // Safari doesn't support requestIdleCallback + // https://caniuse.com/requestidlecallback + window.setTimeout(hydrate, 1); +} diff --git a/templates/cloudflare-workers/app/entry.server.tsx b/templates/cloudflare-workers/app/entry.server.tsx index 9bbd3d2f0f9..9753abb9b04 100644 --- a/templates/cloudflare-workers/app/entry.server.tsx +++ b/templates/cloudflare-workers/app/entry.server.tsx @@ -1,21 +1,42 @@ import type { EntryContext } from "@remix-run/cloudflare"; import { RemixServer } from "@remix-run/react"; -import { renderToString } from "react-dom/server"; +import { renderToReadableStream } from "react-dom/server"; -export default function handleRequest( +export default async function handleRequest( request: Request, responseStatusCode: number, responseHeaders: Headers, remixContext: EntryContext ) { - const markup = renderToString( - - ); - - responseHeaders.set("Content-Type", "text/html"); - - return new Response("" + markup, { - status: responseStatusCode, - headers: responseHeaders, - }); + let controller = new AbortController(); + let didError = false; + try { + const stream = await renderToReadableStream( + , + { + signal: controller.signal, + onError(error: unknown) { + didError = true; + console.error(error); + } + } + ); + + responseHeaders.set("Content-Type", "text/html"); + + return new Response(stream, { + status: didError ? 500 : responseStatusCode, + headers: responseHeaders, + }); + } catch (error: unknown) { + console.error(error); + const message = error instanceof Error ? error.message : "Unknown Error"; + return new Response( + `

An error ocurred:

${message}
`, + { + status: 500, + headers: { "Content-Type": "text/html" }, + } + ); + } } diff --git a/templates/cloudflare-workers/package.json b/templates/cloudflare-workers/package.json index 89af6ff8aaa..de7b4d19b22 100644 --- a/templates/cloudflare-workers/package.json +++ b/templates/cloudflare-workers/package.json @@ -14,15 +14,15 @@ "@remix-run/cloudflare-workers": "*", "@remix-run/react": "*", "cross-env": "^7.0.3", - "react": "^17.0.2", - "react-dom": "^17.0.2" + "react": "^18.2.0", + "react-dom": "^18.2.0" }, "devDependencies": { "@cloudflare/workers-types": "^3.14.1", "@remix-run/dev": "*", "@remix-run/eslint-config": "*", - "@types/react": "^17.0.47", - "@types/react-dom": "^17.0.17", + "@types/react": "^18.0.24", + "@types/react-dom": "^18.0.8", "eslint": "^8.23.1", "miniflare": "^2.6.0", "npm-run-all": "^4.1.5", diff --git a/templates/cloudflare-workers/wrangler.toml b/templates/cloudflare-workers/wrangler.toml index da847772c99..48308a809e2 100644 --- a/templates/cloudflare-workers/wrangler.toml +++ b/templates/cloudflare-workers/wrangler.toml @@ -4,6 +4,7 @@ workers_dev = true main = "./build/index.js" # https://developers.cloudflare.com/workers/platform/compatibility-dates compatibility_date = "2022-04-05" +compatibility_flags = ["streams_enable_constructors"] [site] bucket = "./public"