Erstellen produktionsbereiter SSR-Reaktionsanwendungen
In einer Welt, in der jede Millisekunde zählt, ist serverseitiges Rendering zu einer wesentlichen Funktion für Frontend-Anwendungen geworden.
Dieser Leitfaden führt Sie durch die grundlegenden Muster zum Aufbau eines produktionsbereiten SSR mit React. Sie erhalten ein Verständnis für die Prinzipien hinter React-basierten Frameworks mit integriertem SSR (wie Next.js) und lernen, wie Sie Ihre eigenen benutzerdefinierten Lösungen erstellen.
Der bereitgestellte Code ist produktionsbereit und umfasst einen vollständigen Build-Prozess für Client- und Serverteile, einschließlich einer Docker-Datei. In dieser Implementierung wird Vite zum Erstellen des Client- und SSR-Codes verwendet, Sie können jedoch auch andere Tools Ihrer Wahl verwenden. Vite ermöglicht dem Client auch Hot-Reloading während des Entwicklungsmodus.
Wenn Sie an einer Version dieses Setups ohne Vite interessiert sind, können Sie sich gerne an uns wenden.
Inhaltsverzeichnis
- Was ist SSR?
-
Erstellen der App
- Vite wird initialisiert
- React-Komponenten aktualisieren
- Server erstellen
- Konfigurieren des Builds
- Routing
- Docker
- Fazit
Was ist SSR?
Serverseitiges Rendering (SSR) ist eine Technik in der Webentwicklung, bei der der Server den HTML-Inhalt einer Webseite generiert, bevor er ihn an den Browser sendet. Im Gegensatz zum herkömmlichen clientseitigen Rendering (CSR), bei dem JavaScript den Inhalt auf dem Gerät des Benutzers erstellt, nachdem eine leere HTML-Shell geladen wurde, liefert SSR vollständig gerendertes HTML direkt vom Server.
Hauptvorteile von SSR:
- Verbesserte SEO: Da Suchmaschinen-Crawler vollständig gerenderte Inhalte erhalten, sorgt SSR für eine bessere Indexierung und Rangliste.
- Schnellerer erster Paint: Benutzer sehen aussagekräftige Inhalte fast sofort, da der Server die schwere Arbeit übernimmt Rendering.
- Verbesserte Leistung: Durch die Reduzierung der Rendering-Arbeitslast im Browser sorgt SSR für ein reibungsloseres Erlebnis Benutzer auf älteren oder weniger leistungsstarken Geräten.
- Nahtlose Server-zu-Client-Datenübertragung: SSR ermöglicht Ihnen die Weitergabe dynamischer serverseitiger Daten an den Client ohne Neuaufbau des Client-Bundles.
Erstellen der App
Der Ablauf Ihrer App mit SSR folgt diesen Schritten:
- Lesen Sie die HTML-Vorlagendatei.
- React initialisieren und eine HTML-Zeichenfolge des App-Inhalts generieren.
- Fügen Sie die generierte HTML-Zeichenfolge in die Vorlage ein.
- Senden Sie den vollständigen HTML-Code an den Browser.
- Passen Sie auf dem Client die HTML-Tags an und hydrieren Sie die Anwendung, sodass sie interaktiv wird.
Vite wird initialisiert
Ich bevorzuge die Vite-Vorlage „pnpm“ und „react-swc-ts“, aber Sie können jedes andere Setup wählen.
pnpm create vite react-ssr-app --template react-swc-ts
Installieren Sie die Abhängigkeiten:
pnpm create vite react-ssr-app --template react-swc-ts
Aktualisieren von Reaktionskomponenten
In einer typischen React-Anwendung gibt es einen einzigen main.tsx-Einstiegspunkt für index.html. Bei SSR benötigen Sie zwei Einstiegspunkte: einen für den Server und einen für den Client.
Server-Einstiegspunkt
Der Node.js-Server führt Ihre App aus und generiert den HTML-Code, indem er Ihre React-Komponenten in einen String (renderToString) rendert.
pnpm install
Client-Einstiegspunkt
Der Browser hydratisiert das vom Server generierte HTML und verbindet es mit dem JavaScript, um die Seite interaktiv zu machen.
Hydration ist der Prozess des Anhängens von Ereignis-Listenern und anderen dynamischen Verhaltensweisen an den vom Server gerenderten statischen HTML-Code.
// ./src/entry-server.tsx import { renderToString } from 'react-dom/server' import App from './App' export function render() { return renderToString(<App />) }
Index.html wird aktualisiert
Aktualisieren Sie die Datei index.html im Stammverzeichnis Ihres Projekts. Das Der Platzhalter ist der Ort, an dem der Server den generierten HTML-Code einfügt.
// ./src/entry-client.tsx import { hydrateRoot } from 'react-dom/client' import { StrictMode } from 'react' import App from './App' import './index.css' hydrateRoot( document.getElementById('root')!, <StrictMode> <App /> </StrictMode>, )
Alle für den Server erforderlichen Abhängigkeiten sollten als Entwicklungsabhängigkeiten (devDependencies) installiert werden, um sicherzustellen, dass sie nicht im Client-Bundle enthalten sind.
Als nächstes erstellen Sie im Stammverzeichnis Ihres Projekts einen Ordner mit dem Namen ./server und fügen die folgenden Dateien hinzu.
Erneutes Exportieren der Hauptserverdatei
Exportieren Sie die Hauptserverdatei erneut. Dadurch wird das Ausführen von Befehlen komfortabler.
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8" /> <link rel="icon" type="image/svg+xml" href="/vite.svg" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Vite + React + TS</title> </head> <body> <div> <h3> Create Server </h3> <p>First, install the dependencies:<br> </p> <pre class="brush:php;toolbar:false">pnpm install -D express compression sirv tsup vite-node nodemon @types/express @types/compression
Konstanten definieren
Die HTML_KEY-Konstante muss mit dem Platzhalterkommentar in index.html übereinstimmen. Andere Konstanten verwalten Umgebungseinstellungen.
// ./server/index.ts export * from './app'
Erstellen des Express-Servers
Richten Sie einen Express-Server mit unterschiedlichen Konfigurationen für Entwicklungs- und Produktionsumgebungen ein.
// ./server/constants.ts export const NODE_ENV = process.env.NODE_ENV || 'development' export const APP_PORT = process.env.APP_PORT || 3000 export const PROD = NODE_ENV === 'production' export const HTML_KEY = `<!--app-html-->`
Konfiguration des Entwicklungsmodus
Verwenden Sie in der Entwicklung die Middleware von Vite, um Anfragen zu verarbeiten und die Datei index.html durch Hot-Reload dynamisch umzuwandeln. Der Server lädt die React-Anwendung und rendert sie bei jeder Anfrage in HTML.
// ./server/app.ts import express from 'express' import { PROD, APP_PORT } from './constants' import { setupProd } from './prod' import { setupDev } from './dev' export async function createServer() { const app = express() if (PROD) { await setupProd(app) } else { await setupDev(app) } app.listen(APP_PORT, () => { console.log(`http://localhost:${APP_PORT}`) }) } createServer()
Konfiguration des Produktionsmodus
Verwenden Sie in der Produktion die Komprimierung, um die Leistung zu optimieren, sirv, um statische Dateien bereitzustellen, und das vorgefertigte Serverpaket, um die App zu rendern.
// ./server/dev.ts import { Application } from 'express' import fs from 'fs' import path from 'path' import { HTML_KEY } from './constants' const HTML_PATH = path.resolve(process.cwd(), 'index.html') const ENTRY_SERVER_PATH = path.resolve(process.cwd(), 'src/entry-server.tsx') export async function setupDev(app: Application) { // Create a Vite development server in middleware mode const vite = await ( await import('vite') ).createServer({ root: process.cwd(), server: { middlewareMode: true }, appType: 'custom', }) // Use Vite middleware for serving files app.use(vite.middlewares) app.get('*', async (req, res, next) => { try { // Read and transform the HTML file let html = fs.readFileSync(HTML_PATH, 'utf-8') html = await vite.transformIndexHtml(req.originalUrl, html) // Load the entry-server.tsx module and render the app const { render } = await vite.ssrLoadModule(ENTRY_SERVER_PATH) const appHtml = await render() // Replace the placeholder with the rendered HTML html = html.replace(HTML_KEY, appHtml) res.status(200).set({ 'Content-Type': 'text/html' }).end(html) } catch (e) { // Fix stack traces for Vite and handle errors vite.ssrFixStacktrace(e as Error) console.error((e as Error).stack) next(e) } }) }
Konfigurieren des Builds
Um die Best Practices für die Erstellung Ihrer Anwendung zu befolgen, sollten Sie alle unnötigen Pakete ausschließen und nur das einschließen, was Ihre Anwendung tatsächlich verwendet.
Aktualisieren der Vite-Konfiguration
Aktualisieren Sie Ihre Vite-Konfiguration, um den Build-Prozess zu optimieren und SSR-Abhängigkeiten zu verarbeiten:
// ./server/prod.ts import { Application } from 'express' import fs from 'fs' import path from 'path' import compression from 'compression' import sirv from 'sirv' import { HTML_KEY } from './constants' const CLIENT_PATH = path.resolve(process.cwd(), 'dist/client') const HTML_PATH = path.resolve(process.cwd(), 'dist/client/index.html') const ENTRY_SERVER_PATH = path.resolve(process.cwd(), 'dist/ssr/entry-server.js') export async function setupProd(app: Application) { // Use compression for responses app.use(compression()) // Serve static files from the client build folder app.use(sirv(CLIENT_PATH, { extensions: [] })) app.get('*', async (_, res, next) => { try { // Read the pre-built HTML file let html = fs.readFileSync(HTML_PATH, 'utf-8') // Import the server-side render function and generate HTML const { render } = await import(ENTRY_SERVER_PATH) const appHtml = await render() // Replace the placeholder with the rendered HTML html = html.replace(HTML_KEY, appHtml) res.status(200).set({ 'Content-Type': 'text/html' }).end(html) } catch (e) { // Log errors and pass them to the error handler console.error((e as Error).stack) next(e) } }) }
Aktualisierung von tsconfig.json
Aktualisieren Sie Ihre tsconfig.json, um die Serverdateien einzuschließen, und konfigurieren Sie TypeScript entsprechend:
pnpm create vite react-ssr-app --template react-swc-ts
Tsup-Konfiguration erstellen
Verwenden Sie tsup, einen TypeScript-Bundler, um den Servercode zu erstellen. Die Option noExternal gibt die Pakete an, die mit dem Server gebündelt werden sollen. Stellen Sie sicher, dass Sie alle zusätzlichen Pakete einschließen, die Ihr Server verwendet.
pnpm install
Build-Skripte hinzufügen
// ./src/entry-server.tsx import { renderToString } from 'react-dom/server' import App from './App' export function render() { return renderToString(<App />) }
Ausführen der Anwendung
Entwicklung: Verwenden Sie den folgenden Befehl, um die Anwendung mit Hot-Neuladen zu starten:
// ./src/entry-client.tsx import { hydrateRoot } from 'react-dom/client' import { StrictMode } from 'react' import App from './App' import './index.css' hydrateRoot( document.getElementById('root')!, <StrictMode> <App /> </StrictMode>, )
Produktion: Erstellen Sie die Anwendung und starten Sie den Produktionsserver:
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8" /> <link rel="icon" type="image/svg+xml" href="/vite.svg" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Vite + React + TS</title> </head> <body> <div> <h3> Create Server </h3> <p>First, install the dependencies:<br> </p> <pre class="brush:php;toolbar:false">pnpm install -D express compression sirv tsup vite-node nodemon @types/express @types/compression
Um zu überprüfen, ob SSR funktioniert, überprüfen Sie die erste Netzwerkanfrage an Ihren Server. Die Antwort sollte den vollständig gerenderten HTML-Code Ihrer Anwendung enthalten.
Routenführung
Um Ihrer App verschiedene Seiten hinzuzufügen, müssen Sie das Routing richtig konfigurieren und es sowohl in Client- als auch in Server-Einstiegspunkten verarbeiten.
// ./server/index.ts export * from './app'
Clientseitiges Routing hinzufügen
Umschließen Sie Ihre Anwendung mit BrowserRouter im Client-Einstiegspunkt, um clientseitiges Routing zu ermöglichen.
// ./server/constants.ts export const NODE_ENV = process.env.NODE_ENV || 'development' export const APP_PORT = process.env.APP_PORT || 3000 export const PROD = NODE_ENV === 'production' export const HTML_KEY = `<!--app-html-->`
Serverseitiges Routing hinzufügen
Verwenden Sie StaticRouter im Server-Einstiegspunkt, um das serverseitige Routing zu verwalten. Übergeben Sie die URL als Requisite, um die richtige Route basierend auf der Anfrage darzustellen.
// ./server/app.ts import express from 'express' import { PROD, APP_PORT } from './constants' import { setupProd } from './prod' import { setupDev } from './dev' export async function createServer() { const app = express() if (PROD) { await setupProd(app) } else { await setupDev(app) } app.listen(APP_PORT, () => { console.log(`http://localhost:${APP_PORT}`) }) } createServer()
Aktualisieren von Serverkonfigurationen
Aktualisieren Sie sowohl Ihre Entwicklungs- als auch Ihre Produktionsserver-Setups, um die Anforderungs-URL an die Renderfunktion zu übergeben:
// ./server/dev.ts import { Application } from 'express' import fs from 'fs' import path from 'path' import { HTML_KEY } from './constants' const HTML_PATH = path.resolve(process.cwd(), 'index.html') const ENTRY_SERVER_PATH = path.resolve(process.cwd(), 'src/entry-server.tsx') export async function setupDev(app: Application) { // Create a Vite development server in middleware mode const vite = await ( await import('vite') ).createServer({ root: process.cwd(), server: { middlewareMode: true }, appType: 'custom', }) // Use Vite middleware for serving files app.use(vite.middlewares) app.get('*', async (req, res, next) => { try { // Read and transform the HTML file let html = fs.readFileSync(HTML_PATH, 'utf-8') html = await vite.transformIndexHtml(req.originalUrl, html) // Load the entry-server.tsx module and render the app const { render } = await vite.ssrLoadModule(ENTRY_SERVER_PATH) const appHtml = await render() // Replace the placeholder with the rendered HTML html = html.replace(HTML_KEY, appHtml) res.status(200).set({ 'Content-Type': 'text/html' }).end(html) } catch (e) { // Fix stack traces for Vite and handle errors vite.ssrFixStacktrace(e as Error) console.error((e as Error).stack) next(e) } }) }
Mit diesen Änderungen können Sie jetzt Routen in Ihrer React-App erstellen, die vollständig mit SSR kompatibel sind. Dieser grundlegende Ansatz behandelt jedoch keine verzögert geladenen Komponenten (React.lazy). Informationen zur Verwaltung verzögert geladener Module finden Sie in meinem anderen Artikel, Erweiterte React SSR-Techniken mit Streaming und dynamischen Daten, der unten verlinkt ist.
Docker
Hier ist eine Docker-Datei zum Containerisieren Ihrer Anwendung:
// ./server/prod.ts import { Application } from 'express' import fs from 'fs' import path from 'path' import compression from 'compression' import sirv from 'sirv' import { HTML_KEY } from './constants' const CLIENT_PATH = path.resolve(process.cwd(), 'dist/client') const HTML_PATH = path.resolve(process.cwd(), 'dist/client/index.html') const ENTRY_SERVER_PATH = path.resolve(process.cwd(), 'dist/ssr/entry-server.js') export async function setupProd(app: Application) { // Use compression for responses app.use(compression()) // Serve static files from the client build folder app.use(sirv(CLIENT_PATH, { extensions: [] })) app.get('*', async (_, res, next) => { try { // Read the pre-built HTML file let html = fs.readFileSync(HTML_PATH, 'utf-8') // Import the server-side render function and generate HTML const { render } = await import(ENTRY_SERVER_PATH) const appHtml = await render() // Replace the placeholder with the rendered HTML html = html.replace(HTML_KEY, appHtml) res.status(200).set({ 'Content-Type': 'text/html' }).end(html) } catch (e) { // Log errors and pass them to the error handler console.error((e as Error).stack) next(e) } }) }
Erstellen und Ausführen des Docker-Images
// ./vite.config.ts import { defineConfig } from 'vite' import react from '@vitejs/plugin-react-swc' import { dependencies } from './package.json' export default defineConfig(({ mode }) => ({ plugins: [react()], ssr: { noExternal: mode === 'production' ? Object.keys(dependencies) : undefined, }, }))
{ "include": [ "src", "server", "vite.config.ts" ] }
Abschluss
In diesem Leitfaden haben wir eine solide Grundlage für die Erstellung produktionsbereiter SSR-Anwendungen mit React geschaffen. Sie haben gelernt, wie Sie das Projekt einrichten, das Routing konfigurieren und eine Docker-Datei erstellen. Dieses Setup ist ideal für die effiziente Erstellung von Landingpages oder kleinen Apps.
Entdecken Sie den Kodex
- Beispiel: React-SSR-Basics-Example
- Vorlage: React-SSR-Template
- Vite Extra Template: template-ssr-react-ts
Verwandte Artikel
Dies ist Teil meiner Serie über SSR mit React. Bleiben Sie dran für weitere Artikel!
- Produktionsreife SSR-React-Anwendungen erstellen (Sie sind hier)
- Erweiterte React SSR-Techniken mit Streaming und dynamischen Daten (in Kürze erhältlich)
- Themen in SSR React-Anwendungen einrichten (in Kürze verfügbar)
Bleiben Sie in Verbindung
Ich bin immer offen für Feedback, Zusammenarbeit oder die Diskussion technischer Ideen – zögern Sie nicht, mich zu kontaktieren!
- Portfolio: maxh1t.xyz
- E-Mail: m4xh17@gmail.com
Das obige ist der detaillierte Inhalt vonErstellen produktionsbereiter SSR-Reaktionsanwendungen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

Video Face Swap
Tauschen Sie Gesichter in jedem Video mühelos mit unserem völlig kostenlosen KI-Gesichtstausch-Tool aus!

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen











Python eignet sich besser für Anfänger mit einer reibungslosen Lernkurve und einer kurzen Syntax. JavaScript ist für die Front-End-Entwicklung mit einer steilen Lernkurve und einer flexiblen Syntax geeignet. 1. Python-Syntax ist intuitiv und für die Entwicklung von Datenwissenschaften und Back-End-Entwicklung geeignet. 2. JavaScript ist flexibel und in Front-End- und serverseitiger Programmierung weit verbreitet.

Die Verschiebung von C/C zu JavaScript erfordert die Anpassung an dynamische Typisierung, Müllsammlung und asynchrone Programmierung. 1) C/C ist eine statisch typisierte Sprache, die eine manuelle Speicherverwaltung erfordert, während JavaScript dynamisch eingegeben und die Müllsammlung automatisch verarbeitet wird. 2) C/C muss in den Maschinencode kompiliert werden, während JavaScript eine interpretierte Sprache ist. 3) JavaScript führt Konzepte wie Verschlüsse, Prototypketten und Versprechen ein, die die Flexibilität und asynchrone Programmierfunktionen verbessern.

Zu den Hauptanwendungen von JavaScript in der Webentwicklung gehören die Interaktion der Clients, die Formüberprüfung und die asynchrone Kommunikation. 1) Dynamisches Inhaltsaktualisierung und Benutzerinteraktion durch DOM -Operationen; 2) Die Kundenüberprüfung erfolgt vor dem Einreichung von Daten, um die Benutzererfahrung zu verbessern. 3) Die Aktualisierung der Kommunikation mit dem Server wird durch AJAX -Technologie erreicht.

Die Anwendung von JavaScript in der realen Welt umfasst Front-End- und Back-End-Entwicklung. 1) Zeigen Sie Front-End-Anwendungen an, indem Sie eine TODO-Listanwendung erstellen, die DOM-Operationen und Ereignisverarbeitung umfasst. 2) Erstellen Sie RESTFUFFUPI über Node.js und express, um Back-End-Anwendungen zu demonstrieren.

Es ist für Entwickler wichtig, zu verstehen, wie die JavaScript -Engine intern funktioniert, da sie effizientere Code schreibt und Leistungs Engpässe und Optimierungsstrategien verstehen kann. 1) Der Workflow der Engine umfasst drei Phasen: Parsen, Kompilieren und Ausführung; 2) Während des Ausführungsprozesses führt die Engine dynamische Optimierung durch, wie z. B. Inline -Cache und versteckte Klassen. 3) Zu Best Practices gehören die Vermeidung globaler Variablen, die Optimierung von Schleifen, die Verwendung von const und lass und die Vermeidung übermäßiger Verwendung von Schließungen.

Python und JavaScript haben ihre eigenen Vor- und Nachteile in Bezug auf Gemeinschaft, Bibliotheken und Ressourcen. 1) Die Python-Community ist freundlich und für Anfänger geeignet, aber die Front-End-Entwicklungsressourcen sind nicht so reich wie JavaScript. 2) Python ist leistungsstark in Bibliotheken für Datenwissenschaft und maschinelles Lernen, während JavaScript in Bibliotheken und Front-End-Entwicklungsbibliotheken und Frameworks besser ist. 3) Beide haben reichhaltige Lernressourcen, aber Python eignet sich zum Beginn der offiziellen Dokumente, während JavaScript mit Mdnwebdocs besser ist. Die Wahl sollte auf Projektbedürfnissen und persönlichen Interessen beruhen.

Sowohl Python als auch JavaScripts Entscheidungen in Entwicklungsumgebungen sind wichtig. 1) Die Entwicklungsumgebung von Python umfasst Pycharm, Jupyternotebook und Anaconda, die für Datenwissenschaft und schnelles Prototyping geeignet sind. 2) Die Entwicklungsumgebung von JavaScript umfasst Node.JS, VSCODE und WebPack, die für die Entwicklung von Front-End- und Back-End-Entwicklung geeignet sind. Durch die Auswahl der richtigen Tools nach den Projektbedürfnissen kann die Entwicklung der Entwicklung und die Erfolgsquote der Projekte verbessert werden.

C und C spielen eine wichtige Rolle in der JavaScript -Engine, die hauptsächlich zur Implementierung von Dolmetschern und JIT -Compilern verwendet wird. 1) C wird verwendet, um JavaScript -Quellcode zu analysieren und einen abstrakten Syntaxbaum zu generieren. 2) C ist für die Generierung und Ausführung von Bytecode verantwortlich. 3) C implementiert den JIT-Compiler, optimiert und kompiliert Hot-Spot-Code zur Laufzeit und verbessert die Ausführungseffizienz von JavaScript erheblich.
