برنامه نویسی

React Server Components بدون هیچ چارچوبی

با شروع با Next.js 13، توسعه دهندگان می توانند به قدرت React Server Components دسترسی داشته باشند (از این به بعد فقط از RSC استفاده کنیم). اما اگر نمی خواهید از Next.js استفاده کنید و می خواهید از RSC خارج از جعبه استفاده کنید، پس چگونه باید شروع کنید؟

شما باید از نسخه های آزمایشی استفاده کنید react، react-dom و react-server-dom-webpack.

بیایید یک پروژه جدید راه اندازی کنیم و اینها را نصب کنیم. ما استفاده خواهیم کرد pnpm، زیرا اکنون بهترین و محبوب ترین انتخاب است. همچنین برای راه‌اندازی سریع، از Vite برای سمت کلاینت و از HatTip برای کنترلر پشتیبان خود برای مدیریت راحت‌تر جریان خوانا استفاده می‌کنیم.

mkdir hello-rsc
cd hello-rsc
pnpm init
pnpm add react@experimental react-dom@experimental react-server-dom-webpack@experimental vite @vitejs/plugin-react @hattip/core @hattip/adapter-node
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

برای شروع کار با رندر SSR با Vite، باید چند فایل برای شروع کار ایجاد کنیم.

SSR

ما به یک نیاز خواهیم داشت index.html فایل، که الگوی HTML SSR ما خواهد بود، که اسکریپت ورودی مشتری را بارگیری می کند. این بسیار بسیار کم است.

<script type="module" src="index.jsx"></script>
<div id="root"></div>
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

برای راه اندازی سرور توسعه Vite دارای SSR، اجازه دهید یک سرور ایجاد کنیم index.mjs فایل، که در آن سرور توسعه Vite را در حالت میان‌افزار و با آن نمونه‌سازی می‌کنیم “ssr” به عنوان نوع برنامه

import { createMiddleware } from "@hattip/adapter-node";
import { createServer as createViteDevServer } from "vite";
import react from "@vitejs/plugin-react";
import { readFile } from "node:fs/promises";

const viteDevServer = await createViteDevServer({
  server: {
    middlewareMode: true,
  },
  appType: "ssr",
  plugins: [react()],
});
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

ما باید خود را از قبل بارگذاری کنیم index.html برای استفاده بعدی پس بیایید فایل را همانطور که هست بخوانیم.

const html = await readFile("./index.html", "utf-8");
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

کنترل کننده HatTip زیر روتر ما برای رسیدگی به درخواست هایی خواهد بود که پاسخ RSC را می پذیرد. اگر Accept هدر شامل text/x-component نوع MIME، سپس می دانیم که مشتری به پاسخ در قالب RSC نیاز دارد.

فرمت RSC یک فرمت JSON مانند است که شامل تمام عناصر React است که مشتری ارائه خواهد کرد.

0:"$L1"
1:[["$","h1",null,{"children":"Hello World!"}],["$","h2",null,{"children":["Darwin"," ","x64"," ","22.5.0"]}],"2023-07-07T12:40:30.880Z"]
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

پیاده سازی ما بارگذاری می شود rsc.jsx ماژول SSR با استفاده از Vite و با استفاده از render تابعی که RSC را به یک جریان قابل خواندن تبدیل می کند. ما همچنین برخی از مدیریت خطاهای اساسی را انجام می دهیم.

const ssr = createMiddleware(async ({ request }) => {
  if (request.headers.get("accept").includes("text/x-component")) {
    try {
      const { render } = await viteDevServer.ssrLoadModule("./rsc.jsx");
      return new Response(await render(), {
        headers: {
          "content-type": "text/x-component",
        },
      });
    } catch (e) {
      return new Response(e.stack, {
        status: 500,
        headers: {
          "content-type": "text/plain",
        },
      });
    }
  }
  return new Response(
    await viteDevServer.transformIndexHtml(request.url, html),
    {
      headers: {
        "content-type": "text/html",
      },
    }
  );
});
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در پایان، فقط باید شروع به گوش دادن به درخواست ها با استفاده از سرور توسعه Vite کنیم. به عنوان

viteDevServer.middlewares.use(ssr);
viteDevServer.middlewares.listen(3000).on("listening", () => {
  console.log("Listening on http://localhost:3000");
});
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

React Server Component

چگونه rsc.jsx به نظر می رسد؟ واقعا خیلی ساده است. ماژول اصلی وارداتی که باید مراقب آن باشیم، است react-server-dom-webpack/server.edge. ما <App /> کامپوننت یک تابع همگام است، بنابراین ما می توانیم استفاده کنیم await در داخل آن و در پایان، فقط JSX را برگردانید، جایی که می‌توانیم عملکرد فقط سمت سرور را نیز درج کنیم، بنابراین اطلاعات مربوط به سیستم‌عامل خود و زمان فعلی را به مشتری می‌دهیم. اما ابتدا پاسخ را کمی به تاخیر می اندازیم.

import { renderToReadableStream } from "react-server-dom-webpack/server.edge";
import * as OS from "node:os";

async function delay(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

async function App() {
  await delay(500);
  return (
    <>
      <h1>Hello World!</h1>
      <h2>
        {OS.type()} {OS.arch()} {OS.release()}
      </h2>
      {new Date().toISOString()}
    </>
  );
}

export async function render() {
  return renderToReadableStream(<App />);
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

صادر شده render تابعی است که ما در آن استفاده کردیم index.mjs کنترل کننده، بارگذاری شده با Vite به عنوان یک ماژول SSR.

مشتری

آخرین قسمتی که باید پیاده سازی کنیم ورودی کلاینت است، جایی که ریشه React خود را ایجاد می کنیم تا پاسخ RSC را ارائه دهیم.

import { Suspense } from "react";
import { createRoot } from "react-dom/client";
import { createFromFetch } from "react-server-dom-webpack/client.browser";

let rsc = null;
function App() {
  if (!rsc) {
    rsc = createFromFetch(
      fetch("/app", {
        headers: {
          Accept: "text/x-component",
        },
      })
    );
  }

  return rsc;
}

const root = createRoot(document.getElementById("root"));
root.render(
  <Suspense fallback="Loading...">
    <App />
  </Suspense>
);
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

باید a اضافه کنیم Suspense اطراف ما <App /> کامپوننت تا زمانی که کلاینت پاسخ RSC را دریافت می کند، پیام بارگیری مجدد را نشان می دهد.

ما همچنین باید نتیجه را “کش” کنیم createFromFetch از آنجایی که ما نمی‌خواهیم این بیش از یک بار اجرا شود و همیشه باید یکسان باشد، بنابراین React می‌تواند این مشکل را کنترل کند. <App /> جزء به درستی

بهبود آینده

در حال حاضر، رندر RSC ما از اجزای مشتری پشتیبانی نمی کند ('use client')، فقط عناصر رندر شده در سمت سرور. ما همچنین از اقدامات سرور در این پیاده سازی پشتیبانی نمی کنیم. اینها موضوعات بسیار پیشرفته تری هستند و شما باید از Next.js 13 برای این یا متا فریمورک دیگری که از این ویژگی ها پشتیبانی می کند استفاده کنید.

مطمئناً این فقط یک است “سلام دنیا!” پیاده سازی سطح و می تواند بهبود یابد، اما شاید این نقطه شروع خوبی باشد که می خواهید با برخی از پیاده سازی های سطح پایین در رابطه با React Server Components بازی کنید.

در این مخزن می توانید به کد دسترسی پیدا کنید

با تشکر از خواندن، لطفا روی دنبال کردن کلیک کنید و روز خوبی داشته باشید!

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا