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></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></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.
<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> <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></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></app> </strictmode>, )
Produktion: Erstellen Sie die Anwendung und starten Sie den Produktionsserver:
<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> <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!

Die Auswahl von Python oder JavaScript sollte auf Karriereentwicklung, Lernkurve und Ökosystem beruhen: 1) Karriereentwicklung: Python ist für die Entwicklung von Datenwissenschaften und Back-End-Entwicklung geeignet, während JavaScript für die Entwicklung von Front-End- und Full-Stack-Entwicklung geeignet ist. 2) Lernkurve: Die Python -Syntax ist prägnant und für Anfänger geeignet; Die JavaScript -Syntax ist flexibel. 3) Ökosystem: Python hat reichhaltige wissenschaftliche Computerbibliotheken und JavaScript hat ein leistungsstarkes Front-End-Framework.

Die Kraft des JavaScript -Frameworks liegt in der Vereinfachung der Entwicklung, der Verbesserung der Benutzererfahrung und der Anwendungsleistung. Betrachten Sie bei der Auswahl eines Frameworks: 1. Projektgröße und Komplexität, 2. Teamerfahrung, 3. Ökosystem und Community -Unterstützung.

Einführung Ich weiß, dass Sie es vielleicht seltsam finden. Was genau muss JavaScript, C und Browser tun? Sie scheinen nicht miteinander verbunden zu sein, aber tatsächlich spielen sie eine sehr wichtige Rolle in der modernen Webentwicklung. Heute werden wir die enge Verbindung zwischen diesen drei diskutieren. In diesem Artikel erfahren Sie, wie JavaScript im Browser ausgeführt wird, die Rolle von C in der Browser -Engine und wie sie zusammenarbeiten, um das Rendern und die Interaktion von Webseiten voranzutreiben. Wir alle kennen die Beziehung zwischen JavaScript und Browser. JavaScript ist die Kernsprache der Front-End-Entwicklung. Es läuft direkt im Browser und macht Webseiten lebhaft und interessant. Haben Sie sich jemals gefragt, warum Javascr

Node.js zeichnet sich bei effizienten E/A aus, vor allem bei Streams. Streams verarbeiten Daten inkrementell und vermeiden Speicherüberladung-ideal für große Dateien, Netzwerkaufgaben und Echtzeitanwendungen. Die Kombination von Streams mit der TypeScript -Sicherheit erzeugt eine POWE

Die Unterschiede in der Leistung und der Effizienz zwischen Python und JavaScript spiegeln sich hauptsächlich in: 1 wider: 1) Als interpretierter Sprache läuft Python langsam, weist jedoch eine hohe Entwicklungseffizienz auf und ist für eine schnelle Prototypentwicklung geeignet. 2) JavaScript ist auf einen einzelnen Thread im Browser beschränkt, aber Multi-Threading- und Asynchronen-E/A können verwendet werden, um die Leistung in Node.js zu verbessern, und beide haben Vorteile in tatsächlichen Projekten.

JavaScript stammt aus dem Jahr 1995 und wurde von Brandon Ike erstellt und realisierte die Sprache in C. 1.C-Sprache bietet Programmierfunktionen auf hoher Leistung und Systemebene für JavaScript. 2. Die Speicherverwaltung und die Leistungsoptimierung von JavaScript basieren auf C -Sprache. 3. Die plattformübergreifende Funktion der C-Sprache hilft JavaScript, auf verschiedenen Betriebssystemen effizient zu laufen.

JavaScript wird in Browsern und Node.js -Umgebungen ausgeführt und stützt sich auf die JavaScript -Engine, um Code zu analysieren und auszuführen. 1) abstrakter Syntaxbaum (AST) in der Parsenstufe erzeugen; 2) AST in die Kompilierungsphase in Bytecode oder Maschinencode umwandeln; 3) Führen Sie den kompilierten Code in der Ausführungsstufe aus.

Zu den zukünftigen Trends von Python und JavaScript gehören: 1. Python wird seine Position in den Bereichen wissenschaftlicher Computer und KI konsolidieren. JavaScript wird die Entwicklung der Web-Technologie fördern. Beide werden die Anwendungsszenarien in ihren jeweiligen Bereichen weiter erweitern und mehr Durchbrüche in der Leistung erzielen.


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

ZendStudio 13.5.1 Mac
Leistungsstarke integrierte PHP-Entwicklungsumgebung

MinGW – Minimalistisches GNU für Windows
Dieses Projekt wird derzeit auf osdn.net/projects/mingw migriert. Sie können uns dort weiterhin folgen. MinGW: Eine native Windows-Portierung der GNU Compiler Collection (GCC), frei verteilbare Importbibliotheken und Header-Dateien zum Erstellen nativer Windows-Anwendungen, einschließlich Erweiterungen der MSVC-Laufzeit zur Unterstützung der C99-Funktionalität. Die gesamte MinGW-Software kann auf 64-Bit-Windows-Plattformen ausgeführt werden.

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

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

EditPlus chinesische Crack-Version
Geringe Größe, Syntaxhervorhebung, unterstützt keine Code-Eingabeaufforderungsfunktion
