Tutorial

Aktivieren des serverseitige Rendern für eine React-App

Published on November 23, 2020
authorauthor

Alligator.io and Bradley Kouchi

Deutsch
Aktivieren des serverseitige Rendern für eine React-App

Einführung

Serverseitiges Rendern (SSR) ist eine beliebte Technik zum Rendern einer Client-seitigen Einzelseitenanwendung (SPA) auf dem Server und zum anschließenden Senden einer vollständig gerenderten Seite an den Client. Dadurch werden dynamische Komponenten als statisches HTML-Markup bereitgestellt.

Dieser Ansatz kann für die Suchmaschinenoptimierung (SEO) hilfreich sein, wenn die Indizierung JavaScript nicht richtig verarbeitet. Dies kann auch in Situationen von Vorteil sein, in denen das Herunterladen eines großen JavaScript-Bundles durch ein langsames Netzwerk beeinträchtigt wird.

In diesem Tutorial initialisieren Sie eine React-App mit Create React App und ändern das Projekt, um das serverseitige Rendern zu aktivieren.

Am Ende dieses Tutorials haben Sie ein Arbeitsprojekt mit einer Client-seitigen React-Anwendung und einer serverseitigen Express-Anwendung.

Hinweis: Alternativ bietet Next.js einen modernen Ansatz zum Erstellen statischer und vom Server gerenderter Anwendungen, die mit React erstellt wurden.

Voraussetzungen

Um diesem Tutorial zu folgen, benötigen Sie:

Dieses Tutorial wurde mit Node v14.40 und npm v6.14.5 verifiziert.

Schritt 1 — Erstellen der React-Anwendung und Ändern der App-Komponente

Zuerst verwenden wir npx, um eine neue React-Anwendung mit der neuesten Version der Create React App zu starten.

Rufen wir unsere App my-ssr-app auf:

  1. npx create-react-app@3.4.1 my-ssr-app

Dann nehmen wir cd in die neue Anweisung auf:

cd my-ssr-app

Schließlich starten wir unsere neue Client-seitige App, um die Installation zu verifizieren:

  1. npm start

Sie sollten eine Beispiel-React-App-Anzeige in Ihrem Browser-Fenster sehen.

Lassen Sie uns nun eine <Home>-Komponente erstellen:

  1. nano src/Home.js

Fügen Sie als Nächstes den folgenden Code in die Datei Home.js ein:

src/Home.js
import React from 'react';

export default props => {
  return <h1>Hello {props.name}!</h1>;
};

Dadurch wird eine <h1>-Überschrift mit einer "Hello"-Nachricht erstellt, die an einen Namen geleitet wird.

Als Nächstes rendern wir das <Home> in der <App>-Komponente. Öffnen Sie die Datei App.js:

  1. nano src/App.js

Ersetzen Sie dann die vorhandenen Codezeilen durch diese neuen Codezeilen:

src/App.js
import React from 'react';
import Home from './Home';

export default () => {
  return <Home name="Sammy" />;
};

Dadurch wird ein Name an die <Home>-Komponente übergeben, sodass die Nachricht, die wir erwarten, "Hello Sammy!" lautet.

In der Datei index.js unserer App verwenden wir die ReactDOM-Hydratmethode anstelle des Renderns, um dem DOM-Renderer anzuzeigen, dass wir die App nach einem serverseitigen Rendern rehydrieren.

Öffnen wir die Datei index.js:

  1. nano index.js

Ersetzen Sie dann den Inhalt der Datei index.js durch den folgenden Code:

index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.hydrate(<App />, document.getElementById('root'));

Damit wird die Einrichtung der Client-Seite abgeschlossen, wir können mit der Einrichtung der Server-Seite fortfahren.

Schritt 2 — Erstellen eines Express-Servers und Rendern der App-Komponente

Nachdem wir nun unsere Anwendung eingerichtet haben, richten wir einen Server ein, der eine gerenderte Version übergeben wird. Wir verwenden Express für unseren Server. Fügen wir es dem Projekt hinzu, indem wir den folgenden Befehl in Ihrem Terminalfenster eingeben:

  1. npm install express@4.17.1

Oder mit yarn:

  1. yarn add express@4.17.1

Erstellen Sie als Nächstes ein Server-Verzeichnis neben dem Verzeichnis src der App:

  1. mkdir server

Erstellen Sie dann eine neue Datei index.js, die den Express-Servercode enthält:

  1. nano server/index.js

Fügen Sie die Importe hinzu, die einige Konstanten benötigen, und definieren Sie diese auch:

server/index.js
import path from 'path';
import fs from 'fs';

import React from 'react';
import express from 'express';
import ReactDOMServer from 'react-dom/server';

import App from '../src/App';

const PORT = process.env.PORT || 3006;
const app = express();

Fügen Sie als Nächstes den Servercode mit einer Fehlerbehandlung hinzu:

server/index.js
// ...

app.get('/', (req, res) => {
  const app = ReactDOMServer.renderToString(<App />);

  const indexFile = path.resolve('./build/index.html');
  fs.readFile(indexFile, 'utf8', (err, data) => {
    if (err) {
      console.error('Something went wrong:', err);
      return res.status(500).send('Oops, better luck next time!');
    }

    return res.send(
      data.replace('<div id="root"></div>', `<div id="root">${app}</div>`)
    );
  });
});

app.use(express.static('./build'));

app.listen(PORT, () => {
  console.log(`Server is listening on port ${PORT}`);
});

Wie Sie möglicherweise sehen, können wir unsere <App>-Komponente aus der Client-App direkt vom Server importieren.

Hier finden drei wichtige Dinge statt:

  • Wir weisen Express an, Inhalte aus dem Verzeichnis build als statische Dateien zu verwenden.
  • Wir verwenden eine Methode von ReactDOMServer, renderToString, um unsere App zu einer statischen HTML-Zeichenfolge zu rendern.
  • Dann lesen wir die statische Datei index.html aus der integrierten Client-App, injizieren den statischen Inhalt unserer App im <div> mit einer ID von "root", und senden dies als Antwort auf die Anfrage.

Schritt 3 — Konfigurieren von webpack, Babel und npm Scripts

Damit unser Servercode funktioniert, müssen wir ihn mit webpack und Babel bündeln und transpilieren. Dazu fügen wir dem Projekt die Abhängigkeiten dev hinzu, indem wir den folgenden Befehl in Ihrem Terminalfenster eingeben:

  1. npm install webpack@4.42.0 webpack-cli@3.3.12 webpack-node-externals@1.7.2 @babel/core@7.10.4 babel-loader@8.1.0 @babel/preset-env@7.10.4 @babel/preset-react@7.10.4 --save-dev

Oder mit yarn:

  1. yarn add webpack@4.42.0 webpack-cli@3.3.12 webpack-node-externals@1.7.2 @babel/core@7.10.4 babel-loader@8.1.0 @babel/preset-env@7.10.4 @babel/preset-react@7.10.4 --dev

Hinweis: Eine frühere Version dieses Tutorials installierte babel-core, babel-preset-env und babel-preset-react-app. Diese Pakete wurden seitdem archiviert, und die mono-repo-Versionen werden stattdessen verwendet.

Erstellen Sie als Nächstes eine Babel-Konfigurationsdatei:

  1. nano .babelrc.json

Fügen Sie dann die Voreinstellungen env und react-app hinzu:

.babelrc.json
{
  "presets": [
    "@babel/preset-env",
    "@babel/preset-react"
  ]
}

Anmerkung: Eine frühere Version dieses Tutorials verwendete eine .babelrc-Datei (keine .json-Dateierweiterung). Dies war eine Konfigurationsdatei für Babel 6, aber dies ist für Babel 7 nicht mehr der Fall.

Jetzt erstellen wir eine webpack-Konfiguration für den Server, der Babel Loader verwendet, um den Code zu transpilieren. Beginnen Sie mit der Erstellung der Datei:

  1. nano webpack.server.js

Fügen Sie dann die folgenden Konfigurationen in die webpack.server.js-Datei ein:

webpack.server.js
const path = require('path');
const nodeExternals = require('webpack-node-externals');

module.exports = {
  entry: './server/index.js',

  target: 'node',

  externals: [nodeExternals()],

  output: {
    path: path.resolve('server-build'),
    filename: 'index.js'
  },

  module: {
    rules: [
      {
        test: /\.js$/,
        use: 'babel-loader'
      }
    ]
  }
};

Mit dieser Konfiguration wird unser transpiliertes Serverbundle an den Ordner server-build in einer Datei namens index.js ausgegeben.

Beachten Sie die Verwendung von target: 'node' und externals: [nodeExternals()] aus webpack-node-externals, wodurch die Dateien aus node_modules im Bundle versagt werden; der Server kann direkt auf diese Dateien zugreifen.

Dadurch wird die Abhängigkeit von der Installation und der webpack- und Babel-Konfiguration abgeschlossen.

Jetzt besuchen wir erneut package.json, um Helfer-npm-Scripts hinzuzufügen:

  1. nano package.json

Wir fügen der Datei package.json die Scripts dev:build-server, dev:start und dev hinzu, um unsere SSR-Anwendung leicht zu erstellen und zu bedienen:

package.json
"scripts": {
  "dev:build-server": "NODE_ENV=development webpack --config webpack.server.js --mode=development -w",
  "dev:start": "nodemon ./server-build/index.js",
  "dev": "npm-run-all --parallel build dev:*",
  ...
},

Wir verwenden nodemon, um den Server neu zu starten, wenn wir Änderungen daran durchführen. Und wir verwenden npm-run-all, um mehrere Befehle parallel auszuführen.

Installieren wir diese Pakete nun durch Eingabe der folgenden Befehle in Ihrem Terminalfenster

  1. npm install nodemon@2.0.4 npm-run-all@4.1.5 --save-dev

Oder mit yarn:

  1. yarn add nodemon@2.0.4 npm-run-all@4.1.5 --dev

Damit können Sie Folgendes ausführen, um die Client-seitige App zu erstellen, den Servercode zu bündeln und zu transpilieren, und den Server unter :3006 zu starten:

  1. npm run dev

Oder mit yarn:

  1. yarn run dev

Unsere Server-Webpack-Konfiguration wir auf Änderungen achten und unser Server wird bei Änderungen neu starten. Für die Client-Anwendung müssen wir sie jedoch derzeit immer noch jedes Mal erstellen, wenn wir Änderungen vornehmen. Dafür gibt es hier ein offenes Problem.

Öffnen Sie nun http://localhost:3006/ in Ihrem Webbrowser und Sie sehen Ihre App auf der Serverseite gerendered.

Zuvor hat der Quellcode enthüllt:

Output
<div id="root"></div>

Mit den Änderungen, die Sie vorgenommen haben, enthüllt der Quellcode nun aber:

Output
<div id="root"><h1 data-reactroot="">Hello <!-- -->Sammy<!-- -->!</h1></div>

Das serverseitige Rendering hat die <App>-Komponente erfolgreich in HTML konvertiert.

Zusammenfassung

In diesem Tutorial haben Sie eine React-Anwendung initialisiert und das serverseitige Rendering aktiviert.

In diesem Beitrag haben wir erst einen Bruchteil des Möglichen besprochen. Die Dinge werden etwas komplizierter, wenn Routing, Datenabruf oder Redux ebenfalls Teil einer serverseitig gerenderten App sein müssen.

Ein Hauptvorteil der Verwendung von SSR besteht darin, dass eine App für ihren Inhalt gecrawlt werden kann, selbst für Crawler, die keinen JavaScript-Code ausführen. Dies kann bei der Suchmaschinenoptimierung (SEO) und der Bereitstellung von Metadaten für Social-Media-Kanäle hilfreich sein.

SSR kann auch häufig zur Leistungssteigerung beitragen, da bei der ersten Anforderung eine vollständig geladene App vom Server gesendet wird. Bei nicht trivialen Apps kann Ihr Kilometerstand variieren, da für SSR ein Setup erforderlich ist, das etwas kompliziert werden kann und den Server stärker belastet. Ob Sie serverseitiges Rendering für Ihre React-App verwenden, hängt von Ihren spezifischen Anforderungen ab und davon, welche Kompromisse für Ihren Anwendungsfall am sinnvollsten sind.

Wenn Sie mehr über React erfahren möchten, sehen Sie sich unsere Reihe Codieren in React.js an oder besuchen Sie unsere React-Themenseite für Übungen und Programmierprojekte.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products

About the authors
Default avatar
Alligator.io

author



Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
Leave a comment


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Featured on Community

Get our biweekly newsletter

Sign up for Infrastructure as a Newsletter.

Hollie's Hub for Good

Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

Become a contributor

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

Welcome to the developer cloud

DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

Learn more
DigitalOcean Cloud Control Panel