Migration von Create React App zu Next.js
Diese Anleitung hilft Ihnen dabei, eine bestehende Create React App (CRA)-Website zu Next.js zu migrieren.
Gründe für den Wechsel
Es gibt mehrere Gründe, warum Sie von Create React App zu Next.js wechseln möchten:
Langsame anfängliche Ladezeit
Create React App verwendet rein clientseitiges React. Clientseitige Anwendungen, auch bekannt als Single-Page Applications (SPAs), haben oft eine langsame anfängliche Ladezeit. Dies liegt an folgenden Gründen:
- Der Browser muss warten, bis der React-Code und Ihr gesamtes Anwendungs-Bundle heruntergeladen und ausgeführt wurden, bevor Ihr Code Anfragen zum Laden von Daten senden kann.
- Ihr Anwendungscode wächst mit jeder neuen Funktion und Abhängigkeit, die Sie hinzufügen.
Kein automatisches Code-Splitting
Das vorherige Problem der langsamen Ladezeiten kann teilweise durch Code-Splitting gemildert werden. Wenn Sie jedoch versuchen, Code-Splitting manuell durchzuführen, können Sie unbeabsichtigt Netzwerk-Wasserfälle einführen. Next.js bietet automatisches Code-Splitting und Tree-Shaking, das in seinen Router und Build-Prozess integriert ist.
Netzwerk-Wasserfälle
Eine häufige Ursache für schlechte Leistung tritt auf, wenn Anwendungen sequenzielle Client-Server-Anfragen zum Abrufen von Daten stellen. Ein Muster für das Datenabrufen in einer SPA ist das Rendern eines Platzhalters und das anschließende Abrufen von Daten, nachdem die Komponente gemountet wurde. Leider kann eine Kindkomponente erst mit dem Datenabruf beginnen, nachdem ihre Elternkomponente ihre eigenen Daten vollständig geladen hat, was zu einem "Wasserfall" von Anfragen führt.
Während clientseitiges Datenabrufen in Next.js unterstützt wird, ermöglicht Next.js Ihnen auch, das Datenabrufen auf den Server zu verlagern. Dadurch werden clientseitige Wasserfälle oft vollständig eliminiert.
Schnelle und gezielte Ladezustände
Mit integrierter Unterstützung für Streaming durch React Suspense können Sie definieren, welche Teile Ihrer Benutzeroberfläche zuerst und in welcher Reihenfolge geladen werden, ohne Netzwerk-Wasserfälle zu erzeugen.
Dies ermöglicht es Ihnen, Seiten zu erstellen, die schneller laden und Layoutverschiebungen vermeiden.
Wählen Sie die Datenabrufstrategie
Abhängig von Ihren Anforderungen ermöglicht Next.js Ihnen, Ihre Datenabrufstrategie auf Seiten- oder Komponentenebene zu wählen. Beispielsweise könnten Sie Daten von Ihrem CMS abrufen und Blogbeiträge zur Build-Zeit (SSG) für schnelle Ladezeiten rendern oder bei Bedarf Daten zur Anfragezeit (SSR) abrufen.
Middleware
Next.js Middleware ermöglicht es Ihnen, Code auf dem Server auszuführen, bevor eine Anfrage abgeschlossen ist. Beispielsweise können Sie ein Aufblitzen von nicht authentifizierten Inhalten vermeiden, indem Sie einen Benutzer in der Middleware für nur authentifizierte Seiten auf eine Login-Seite umleiten. Sie können sie auch für Funktionen wie A/B-Tests, Experimente und Internationalisierung verwenden.
Integrierte Optimierungen
Bilder, Schriftarten und Skripte von Drittanbietern haben oft einen großen Einfluss auf die Leistung einer Anwendung. Next.js enthält spezialisierte Komponenten und APIs, die diese automatisch für Sie optimieren.
Migrationsschritte
Unser Ziel ist es, eine funktionierende Next.js-Anwendung so schnell wie möglich zu erhalten, damit Sie dann Next.js-Funktionen schrittweise übernehmen können. Zunächst behandeln wir Ihre Anwendung als rein clientseitige Anwendung (SPA), ohne Ihren bestehenden Router sofort zu ersetzen. Dies reduziert die Komplexität und Merge-Konflikte.
Hinweis: Wenn Sie erweiterte CRA-Konfigurationen wie ein benutzerdefiniertes
homepage
-Feld in Ihrerpackage.json
, einen benutzerdefinierten Service Worker oder spezifische Babel/Webpack-Anpassungen verwenden, lesen Sie bitte den Abschnitt Zusätzliche Überlegungen am Ende dieser Anleitung für Tipps zur Replikation oder Anpassung dieser Funktionen in Next.js.
Schritt 1: Installieren der Next.js-Abhängigkeit
Installieren Sie Next.js in Ihrem bestehenden Projekt:
Schritt 2: Erstellen der Next.js-Konfigurationsdatei
Erstellen Sie eine next.config.ts
im Stammverzeichnis Ihres Projekts (auf derselben Ebene wie Ihre package.json
). Diese Datei enthält Ihre Next.js-Konfigurationsoptionen.
Hinweis: Die Verwendung von
output: 'export'
bedeutet, dass Sie einen statischen Export durchführen. Sie haben keinen Zugriff auf serverseitige Funktionen wie SSR oder APIs. Sie können diese Zeile entfernen, um Next.js-Serverfunktionen zu nutzen.
Schritt 3: Erstellen des Root-Layouts
Eine Next.js-App Router-Anwendung muss eine Root-Layout-Datei enthalten, die eine React Server Component ist und alle Ihre Seiten umschließt.
Die nächste Entsprechung der Root-Layout-Datei in einer CRA-Anwendung ist public/index.html
, die Ihre <html>
, <head>
und <body>
-Tags enthält.
- Erstellen Sie ein neues
app
-Verzeichnis in Ihremsrc
-Ordner (oder im Stammverzeichnis Ihres Projekts, wenn Sieapp
im Stammverzeichnis bevorzugen). - Erstellen Sie im
app
-Verzeichnis einelayout.tsx
(oderlayout.js
)-Datei:
Kopieren Sie nun den Inhalt Ihrer alten index.html
in diese <RootLayout>
-Komponente. Ersetzen Sie body div#root
(und body noscript
) durch <div id="root">{children}</div>
.
Gut zu wissen: Next.js ignoriert standardmäßig CRA’s
public/manifest.json
, zusätzliche Icongrafik und Testkonfiguration. Wenn Sie diese benötigen, bietet Next.js Unterstützung mit seiner Metadata API und Testing-Setup.
Schritt 4: Metadaten
Next.js fügt automatisch die <meta charset="UTF-8" />
und <meta name="viewport" content="width=device-width, initial-scale=1" />
-Tags ein, sodass Sie sie aus <head>
entfernen können:
Jede Metadatendatei wie favicon.ico
, icon.png
, robots.txt
wird automatisch zum <head>
-Tag der Anwendung hinzugefügt, solange Sie sie in der obersten Ebene des app
-Verzeichnisses platziert haben. Nachdem Sie alle unterstützten Dateien in das app
-Verzeichnis verschoben haben, können Sie ihre <link>
-Tags sicher löschen:
Schließlich kann Next.js Ihre letzten <head>
-Tags mit der Metadata API verwalten. Verschieben Sie Ihre letzten Metadateninformationen in ein exportiertes metadata
-Objekt:
Mit den oben genannten Änderungen sind Sie von der Deklaration aller Elemente in Ihrer index.html
zu dem konventionsbasierten Ansatz von Next.js übergegangen, der in das Framework integriert ist (Metadata API). Dieser Ansatz ermöglicht es Ihnen, die SEO und die Teilbarkeit Ihrer Seiten im Web einfacher zu verbessern.
Schritt 5: Stile
Ähnlich wie CRA unterstützt Next.js CSS Modules out of the box. Es unterstützt auch globale CSS-Imports.
Wenn Sie eine globale CSS-Datei haben, importieren Sie sie in Ihre app/layout.tsx
:
Wenn Sie Tailwind CSS verwenden, lesen Sie unsere Installationsdokumentation.
Schritt 6: Erstellen der Einstiegsseite
Create React App verwendet src/index.tsx
(oder index.js
) als Einstiegspunkt. In Next.js (App Router) entspricht jeder Ordner innerhalb des app
-Verzeichnisses einer Route, und jeder Ordner sollte eine page.tsx
enthalten.
Da wir die Anwendung zunächst als SPA behalten und alle Routen abfangen möchten, verwenden wir eine optionale Catch-All-Route.
- Erstellen Sie ein
[[...slug]]
-Verzeichnis innerhalb vonapp
.
- Fügen Sie Folgendes zu
page.tsx
hinzu:
Dies teilt Next.js mit, eine einzelne Route für den leeren Slug (/
) zu generieren, wodurch effektiv alle Routen derselben Seite zugeordnet werden. Diese Seite ist eine Server Component, die in statisches HTML vorgerendert wird.
Schritt 7: Hinzufügen eines Client-Only-Einstiegspunkts
Als Nächstes betten wir die Root-App-Komponente Ihrer CRA in eine Client Component ein, damit die gesamte Logik clientseitig bleibt. Wenn Sie Next.js zum ersten Mal verwenden, ist es wichtig zu wissen, dass Client-Komponenten (standardmäßig) trotzdem auf dem Server vorgerendert werden. Sie können sie sich als mit der zusätzlichen Fähigkeit vorstellen, clientseitiges JavaScript auszuführen.
Erstellen Sie eine client.tsx
(oder client.js
) in app/[[...slug]]/
:
- Die
'use client'
-Direktive macht diese Datei zu einer Client Component. - Der
dynamic
-Import mitssr: false
deaktiviert das Server-Side-Rendering für die<App />
-Komponente, wod sie wirklich clientseitig (SPA) wird.
Aktualisieren Sie nun Ihre page.tsx
(oder page.js
), um Ihre neue Komponente zu verwenden:
Schritt 8: Statische Bildimporte aktualisieren
In CRA gibt der Import einer Bilddatei deren öffentliche URL als Zeichenkette zurück:
Mit Next.js geben statische Bildimporte ein Objekt zurück. Dieses Objekt kann dann direkt mit der Next.js <Image>
-Komponente verwendet werden, oder Sie können die src
-Eigenschaft des Objekts mit Ihrem bestehenden <img>
-Tag nutzen.
Die <Image>
-Komponente bietet zusätzliche Vorteile wie automatische Bildoptimierung. Die <Image>
-Komponente setzt automatisch die width
- und height
-Attribute des resultierenden <img>
basierend auf den Abmessungen des Bildes. Dies verhindert Layoutverschiebungen beim Laden des Bildes. Allerdings kann dies Probleme verursachen, wenn Ihre App Bilder enthält, bei denen nur eine ihrer Abmessungen gestaltet ist, ohne die andere auf auto
zu setzen. Wenn nicht auf auto
gesetzt, wird die Abmessung standardmäßig auf den Wert des <img>
-Dimension-Attributs gesetzt, was zu einer verzerrten Darstellung des Bildes führen kann.
Die Beibehaltung des <img>
-Tags reduziert die Anzahl der Änderungen in Ihrer Anwendung und verhindert die oben genannten Probleme. Sie können später optional zur <Image>
-Komponente migrieren, um von der Optimierung der Bilder durch Konfiguration eines Loaders zu profitieren oder zum standardmäßigen Next.js-Server zu wechseln, der automatische Bildoptimierung bietet.
Konvertieren Sie absolute Importpfade für Bilder aus /public
in relative Importe:
Übergeben Sie die src
-Eigenschaft des Bildes anstelle des gesamten Bildobjekts an Ihr <img>
-Tag:
Alternativ können Sie die öffentliche URL für die Bilddatei basierend auf dem Dateinamen referenzieren. Beispielsweise wird public/logo.png
das Bild unter /logo.png
für Ihre Anwendung bereitstellen, was der src
-Wert wäre.
Warnung: Wenn Sie TypeScript verwenden, könnten Sie Typfehler beim Zugriff auf die
src
-Eigenschaft erhalten. Um diese zu beheben, müssen Sienext-env.d.ts
zuminclude
-Array Ihrertsconfig.json
-Datei hinzufügen. Next.js generiert diese Datei automatisch, wenn Sie Ihre Anwendung in Schritt 9 ausführen.
Schritt 9: Umgebungsvariablen migrieren
Next.js unterstützt Umgebungsvariablen ähnlich wie CRA, erfordert jedoch das Präfix NEXT_PUBLIC_
für jede Variable, die im Browser verfügbar gemacht werden soll.
Der Hauptunterschied ist das Präfix, das verwendet wird, um Umgebungsvariablen clientseitig verfügbar zu machen. Ändern Sie alle Umgebungsvariablen mit dem Präfix REACT_APP_
zu NEXT_PUBLIC_
.
Schritt 10: Skripte in package.json
aktualisieren
Aktualisieren Sie Ihre package.json
-Skripte, um Next.js-Befehle zu verwenden. Fügen Sie außerdem .next
und next-env.d.ts
zu Ihrer .gitignore
hinzu:
Nun können Sie ausführen:
Öffnen Sie http://localhost:3000. Sie sollten Ihre Anwendung nun mit Next.js (im SPA-Modus) laufen sehen.
Schritt 11: Bereinigung
Sie können nun Artefakte entfernen, die spezifisch für Create React App sind:
public/index.html
src/index.tsx
src/react-app-env.d.ts
- Das
reportWebVitals
-Setup - Die
react-scripts
-Abhängigkeit (deinstallieren Sie sie auspackage.json
)
Zusätzliche Überlegungen
Verwendung eines benutzerdefinierten homepage
in CRA
Falls Sie das Feld homepage
in Ihrer CRA-package.json
verwendet haben, um die App unter einem bestimmten Unterpfad bereitzustellen, können Sie dies in Next.js mit der basePath
-Konfiguration in next.config.ts
replizieren:
Handhabung eines benutzerdefinierten Service Worker
Falls Sie den Service Worker von CRA (z.B. serviceWorker.js
aus create-react-app
) verwendet haben, können Sie lernen, wie Sie Progressive Web Applications (PWAs) mit Next.js erstellen.
Proxy für API-Anfragen
Falls Ihre CRA-App das proxy
-Feld in package.json
verwendet hat, um Anfragen an einen Backend-Server weiterzuleiten, können Sie dies mit Next.js Rewrites in next.config.ts
replizieren:
Benutzerdefinierte Webpack-/Babel-Konfiguration
Falls Sie eine benutzerdefinierte Webpack- oder Babel-Konfiguration in CRA hatten, können Sie die Next.js-Konfiguration in next.config.ts
erweitern:
Hinweis: Dies erfordert das Deaktivieren von Turbopack durch Entfernen von
--turbopack
aus Ihremdev
-Skript.
TypeScript-Einrichtung
Next.js richtet TypeScript automatisch ein, wenn eine tsconfig.json
vorhanden ist. Stellen Sie sicher, dass next-env.d.ts
in Ihrem include
-Array der tsconfig.json
aufgeführt ist:
Bundler-Kompatibilität
Sowohl Create React App als auch Next.js verwenden standardmäßig webpack für das Bundling. Next.js bietet auch Turbopack für schnellere lokale Entwicklung mit:
Sie können dennoch eine benutzerdefinierte Webpack-Konfiguration bereitstellen, falls Sie erweiterte Webpack-Einstellungen aus CRA migrieren müssen.
Nächste Schritte
Falls alles funktioniert, haben Sie nun eine funktionierende Next.js-Anwendung, die als Single-Page-Anwendung läuft. Sie nutzen noch keine Next.js-Funktionen wie Server-seitiges Rendering oder dateibasiertes Routing, können dies jedoch nun schrittweise tun:
- Migration von React Router zum Next.js App Router für:
- Automatisches Code-Splitting
- Streaming-Server-Rendering
- React Server Components
- Bilder optimieren mit der
<Image>
-Komponente - Schriftarten optimieren mit
next/font
- Drittanbieter-Skripte optimieren mit der
<Script>
-Komponente - ESLint aktivieren mit den empfohlenen Next.js-Regeln durch Ausführen von
npx next lint
und Anpassen an die Bedürfnisse Ihres Projekts
Hinweis: Die Verwendung eines statischen Exports (
output: 'export'
) unterstützt derzeit nicht denuseParams
-Hook oder andere Server-Features. Um alle Next.js-Features nutzen zu können, entfernen Sieoutput: 'export'
aus Ihrernext.config.ts
.