Ich erstelle eine App, die neben dem React-Router auch den Webpack-Dev-Server in der Entwicklung verwendet.
Es scheint, dass der Webpack-Dev-Server auf der Annahme basiert, dass Sie einen öffentlichen Einstiegspunkt an einem Ort haben (dh "/"), während der React-Router eine unbegrenzte Anzahl von Einstiegspunkten zulässt.
Ich möchte die Vorteile des Webpack-Dev-Servers nutzen, insbesondere die Hot-Reloading-Funktion, die sich positiv auf die Produktivität auswirkt, aber ich möchte weiterhin Routen laden können, die im React-Router festgelegt wurden.
Wie könnte man es so umsetzen, dass sie zusammenarbeiten? Könnten Sie einen Express-Server vor dem Webpack-Dev-Server so betreiben, dass dies möglich ist?
javascript
reactjs
webpack
react-router
Nathan Wienert
quelle
quelle
Antworten:
Ich habe einen Proxy eingerichtet, um dies zu erreichen:
Sie haben einen regulären Express-Webserver, der die index.html auf jeder Route bereitstellt, außer wenn es sich um eine Asset-Route handelt. Wenn es sich um ein Asset handelt, wird die Anforderung an den Web-Dev-Server weitergeleitet
Ihre reaktionsschnellen Einstiegspunkte zeigen weiterhin direkt auf den Webpack-Entwicklungsserver, sodass das Hot-Reloading weiterhin funktioniert.
Angenommen, Sie führen webpack-dev-server unter 8081 und Ihren Proxy unter 8080 aus. Ihre Datei server.js sieht folgendermaßen aus:
Machen Sie jetzt Ihre Einstiegspunkte in der Webpack-Konfiguration wie folgt:
Beachten Sie den direkten Anruf bei 8081 für Hotreload
Stellen Sie außerdem sicher, dass Sie der
output.publicPath
Option eine absolute URL übergeben :quelle
output.publicPath
Option hinzugefügt , der auch eine absolute URL sein sollte.historyApiFallback
.Sie sollten eingestellt
historyApiFallback
vonWebpackDevServer
für diese Arbeit als wahr. Hier ist ein kleines Beispiel (Anpassung an Ihre Zwecke):quelle
true
.webpack-dev-server --history-api-fallback
Für alle anderen, die noch nach dieser Antwort suchen. Ich habe einen einfachen Proxy-Bypass zusammengestellt, der dies ohne großen Aufwand erreicht, und die Konfiguration geht in die Datei webpack.config.js
Ich bin mir sicher, dass es viel elegantere Möglichkeiten gibt, mit Regex auf lokale Inhalte zu testen, aber dies funktioniert für meine Anforderungen.
quelle
Wenn Sie webpack-dev-server mit CLI ausführen, können Sie es über webpack.config.js konfigurieren, indem Sie das devServer-Objekt übergeben:
Dies wird jedes Mal, wenn 404 angetroffen wird, zu index.html umgeleitet.
HINWEIS: Wenn Sie publicPath verwenden, müssen Sie es auch an devServer übergeben:
Sie können überprüfen, ob alles korrekt eingerichtet ist, indem Sie sich die ersten Zeilen der Ausgabe ansehen (der Teil mit "404s wird auf: Pfad zurückgreifen ").
quelle
Für eine neuere Antwort, die aktuelle Version von Webpack (4.1.1), können Sie dies einfach in Ihrer webpack.config.js wie folgt einstellen:
Der wichtige Teil ist
historyApiFallback: true
. Sie müssen keinen benutzerdefinierten Server ausführen. Verwenden Sie einfach die CLI:quelle
Ich möchte die Antwort für den Fall ergänzen, dass Sie eine isomorphe App ausführen (dh die React-Komponente serverseitig rendern).
In diesem Fall möchten Sie den Server wahrscheinlich auch automatisch neu laden, wenn Sie eine Ihrer React-Komponenten ändern. Sie tun dies mit dem
piping
Paket. Alles was Sie tun müssen, ist es zu installieren undrequire("piping")({hook: true})
irgendwo am Anfang Ihrer server.js hinzuzufügen . Das ist es. Der Server wird neu gestartet, nachdem Sie eine von ihm verwendete Komponente geändert haben.Dies wirft jedoch ein weiteres Problem auf: Wenn Sie den Webpack-Server über denselben Prozess wie Ihren Express-Server ausführen (wie in der oben akzeptierten Antwort angegeben), wird der Webpack-Server ebenfalls neu gestartet und Ihr Bundle jedes Mal neu kompiliert. Um dies zu vermeiden, sollten Sie Ihren Hauptserver und Ihren Webpack-Server in unterschiedlichen Prozessen ausführen, damit das Piping nur Ihren Express-Server neu startet und das Webpack nicht berührt. Sie können dies mit
concurrently
Paket tun . Ein Beispiel hierfür finden Sie im React-Isomorphic-Starterkit . In der package.json hat er:Dadurch werden beide Server gleichzeitig, jedoch in separaten Prozessen ausgeführt.
quelle
historyApiFallback
kann auch ein Objekt anstelle eines Booleschen Werts sein, das die Routen enthält.quelle
publicPath: '/'
Möglicherweise nicht in allen Fällen, aber die Option im devServer scheint die einfachste Lösung zu sein, um Probleme mit tiefen Routen zu beheben. Siehe: https://github.com/ReactTraining/react-router/issues/676quelle
Das hat bei mir funktioniert: Fügen Sie einfach zuerst die Webpack-Middleware und später den
app.get('*'...
Resolver index.html hinzu.Express prüft daher zunächst, ob die Anfrage mit einer der vom Webpack bereitgestellten Routen übereinstimmt (wie:
/dist/bundle.js
oder/__webpack_hmr_
). Wenn nicht, wird sieindex.html
mit dem*
Resolver an die weitergeleitet.dh:
quelle