🦕

React Server Componentsだけを使ったサーバオンリーフレームワーク?!

2023/06/20に公開

朝起きたら、こんなツイートが流れてました。

https://twitter.com/tomus_sherman/status/1670854602483281922

それってDeno使えばすぐできるのでは?と思ってやったのがこちら👇

https://twitter.com/dai_shi/status/1670963177897742337

同じコードを載せておきます。

#!/usr/bin/env deno run --allow-net

import { createElement, Suspense } from "https://esm.sh/react@18.3.0-canary-613e6f5fc-20230616";
import { renderToReadableStream } from "https://esm.sh/react-dom@18.3.0-canary-613e6f5fc-20230616/server";

const server = Deno.listen({ port: 8080 });

for await (const conn of server) {
  (async () => {
    const httpConn = Deno.serveHttp(conn);
    for await (const requestEvent of httpConn) {
      await handleRequest(requestEvent);
    }
  })();
}

async function handleRequest(requestEvent: Deno.RequestEvent) {
  const url = requestEvent.request.url;
  await requestEvent.respondWith(
    new Response(await renderToReadableStream(createElement(App, { url })))
  );
}

// Application code

function App({ url }: { url: string }) {
  return (
    <div style={{ border: "3px red dashed", margin: "1em", padding: "1em" }}>
      <h1>Hello {url}!!</h1>
      <h3>This is a server component.</h3>
      <Suspense fallback="Pending...">
        <ServerMessage />
      </Suspense>
    </div>
  );
}

async function ServerMessage() {
  await new Promise((resolve) => setTimeout(resolve, 3000));
  return <p>Hello from server!</p>;
}

動作イメージはこちら。

https://twitter.com/dai_shi/status/1670963385176055808

RSCというかただのJSなし版SSRですね。Next.js 12で実現できていたものかと思います。
SSRストリーミングができるのは良いですね。(React Fizzというコードネーム)
RSC固有の機能(React Flightというコードネーム)は使わなかったです。
もう少し色々やると面白い感じのものができるかもしれません。Server Actionsを実装するとか。

おまけ

何に時間かかったって、neovimのdeno環境がなかったので、プラグイン入れたりしてました。結局JSXのTypeScriptエラーの解決法がよくわからず断念。

Discussion