چگونه استارت پازل Express + Vite SSR را حل می کند

آیا تا به حال سعی کرده اید Express و Vite را برای ارائه سمت سرور در یک برنامه React ترکیب کنید؟
اگر چنین است ، شما احتمالاً با چالش مدیریت دو سرور جداگانه روبرو شده اید و باعث می شود که آنها به راحتی با هم کار کنند.
در این پست ، شما را طی می کنم که چگونه استارت با یک رویکرد “یک سرور” این مشکل را حل می کند که نه تنها توسعه را ساده می کند بلکه قابلیت های قدرتمند ارائه دهنده سرور (SSR) را نیز امکان پذیر می کند.
مشکل: دو سرور ، یک برنامه
هنگام ساختن یک برنامه وب مدرن با React و Express ، معمولاً:
- یک سرور توسعه Vite با تعویض ماژول داغ (HMR) و ویژگی های ویژه React
- یک سرور باکتری اکسپرس مدیریت مسیرهای API و منطق سمت سرور
مدیریت اینها به عنوان سرورهای جداگانه پیچیدگی غیر ضروری را ایجاد می کند:
- شما به تنظیمات پروکسی نیاز دارید
- ارتباط بین سرورها دست و پا گیر می شود
- توسعه محلی نیاز به اجرای چندین فرآیند دارد
- استقرار پیچیده تر می شود
راه حل استارت: یک سرور برای حاکم بر همه آنها
استارت یک رویکرد متفاوت توسط اتصال یک سرور توسعه Vite به سرور برنامه Express، ایجاد یک سرور یکپارچه واحد. این معماری مزایای مختلفی را به همراه دارد:
- گردش کار ساده شده
- ساختار پایه کد پاک کننده
- حذف تنظیمات پیچیده پروکسی
- استقرار ساده
اما قدرتمندترین فایده؟ این امکان را فراهم می کند که طرف سرور از جعبه خارج شود.
چگونه استارت SSR را با Express و Vite پیاده سازی می کند
نکته اصلی اجرای SSR Starter نحوه ادغام حالت میانی Vite با Express در حالی که از قابلیت های رندر استاتیک React Router استفاده می کند.
ساختار هسته
.
├── index.html
├── server.ts # Main application server
└── src
├── entry-client.tsx # Mounts the application on a DOM element
├── entry-server.tsx # Renders the application using Vite's SSR API
└── react
└── routes.tsx # Entry point for React code (client/server agnostic)
این ساختار ضمن حفظ معماری کاربردی منسجم ، نگرانی ها را از هم جدا می کند.
تنظیم سرور توسعه
جادو شروع می شود server.ts
جایی که ما Vite را در حالت Middleware پیکربندی می کنیم:
import express from "express";
import { createServer as createViteServer } from "vite";
const app = express();
const isProduction = process.env.NODE_ENV === "production";
if (!isProduction) {
// Create Vite server in middleware mode
const vite = await createViteServer({
server: { middlewareMode: true },
appType: "custom",
});
// Use vite's connect instance as middleware
app.use(vite.middlewares);
app.use(/(.*)/, async (req, res, next) => {
// Handle SSR rendering
// (We'll explore this next)
});
}
با استفاده از middlewareMode: true
وت appType: "custom"
، ما به Vite می گوییم که سرور اکسپرس ما را کنترل کند در حالی که هنوز تمام ویژگی های توسعه آن را ارائه می دهد.
اجرای ارائه دهنده سمت سرور
سحر و جادو واقعی SSR در کنترل مسیر همه و موارد اتفاق می افتد entry-server.tsx
پرونده Starter از دستگیرهای استاتیک React Router استفاده می کند و renderToPipeableStream
برای ارائه کارآمد با پشتیبانی تعلیق:
app.use(/(.*)/, async (req, res, next) => {
const url = req.originalUrl;
const indexHtml = fs.readFileSync("index.html", "utf-8");
// Transform HTML with Vite plugins
const template = await vite.transformIndexHtml(url, indexHtml);
// Load the server entry module
const { render } = await vite.ssrLoadModule("/src/entry-server");
// Render the app HTML
await render(template, req, res);
});
و در entry-server.tsx
:
import { Transform } from "node:stream";
import { renderToPipeableStream } from "react-dom/server";
import { createStaticHandler, createStaticRouter, StaticRouterProvider } from "react-router";
import routes from "./react/routes";
const { query, dataRoutes } = createStaticHandler(routes);
export const render = async (template, req, res) => {
// Get routing context
const context = await query(
new Request(`${req.protocol}://${req.get("host")}${req.originalUrl}`)
);
// Create a static router for SSR
const router = createStaticRouter(dataRoutes, context);
// Stream the rendered content
const { pipe } = renderToPipeableStream(
<StaticRouterProvider router={router} context={context} />
);
// Respond with streamed HTML
res.status(200).set("Content-Type", "text/html; charset=utf-8");
const [htmlStart, htmlEnd] = template.split("");
res.write(htmlStart);
const transformStream = new Transform({
transform(chunk, encoding, callback) {
res.write(chunk, encoding);
callback();
},
});
pipe(transformStream);
transformStream.on("finish", () => {
res.end(htmlEnd);
});
};
این رویکرد جریان مزایای مختلفی دارد:
- پشتیبانی از React’s
روی سرور - زمان سریعتر به اولین بایت (TTFB)
- ارائه مترقی محتوا
- تجربه بهتر کاربر ، به خصوص در اتصالات کندتر
استقرار
برای تولید ، استارت از یک فرآیند ساخت دو قسمتی استفاده می کند:
{
"scripts": {
"build:client": "vite build --outDir dist/client",
"build:server": "vite build --outDir dist/server --ssr src/entry-server"
}
}
کد سرور سپس به جای استفاده از زمان توسعه Vite ، بسته نرم افزاری SSR از پیش ساخته را در حالت تولید بارگذاری می کند ssrLoadModule
بشر
چرا استارت را برای پروژه بعدی خود انتخاب کنید؟
استارت بیش از یک اجرای SSR است – این یک چارچوب کامل برنامه وب است که برای اهداف آموزشی طراحی شده است که قدرت یا انعطاف پذیری را فدا نمی کند.
مزایای کلیدی:
- تمرکز آموزشی: مناسب برای مبتدیان و کسانی که مهارت های خود را پیش می برند
- توسعه یکپارچه: یک رویکرد سرور پیچیدگی را از بین می برد
- پشته مدرن: React + Express + Vite + SSR
- تولید آماده: فرآیند ساخت بهینه شده برای استقرار
- بهترین روشها: بهترین بسته های موجود در اکوسیستم JS را ترکیب می کند
این که آیا شما در حال یادگیری توسعه وب هستید یا ساخت یک برنامه تولید ، استارت یک پایه محکم را فراهم می کند که به شما امکان می دهد روی آنچه مهم است تمرکز کنید – ساختن ویژگی های برنامه خود.
با استارت شروع کنید
آماده امتحان این رویکرد “یک سرور” برای پروژه React + Express بعدی خود هستید؟
Starter on Github را بررسی کنید و در صورت مفید بودن آن را به آن ستاره بدهید!
جزئیات کامل اجرای عملکرد SSR را می توان در:
با چه چالش های توسعه وب روبرو هستید که استارت ممکن است به حل آن کمک کند؟ بحث را باز کنید تا به من اطلاع دهید!