Wenn Sie Django und React hören, denken Sie vielleicht an einen Microservice-Ansatz mit zwei separaten, getrennt gehosteten Diensten, die über eine HTTP-basierte API kommunizieren. Frontend und Backend sind separate Anwendungen, die als unabhängige Dienste laufen. Die beiden Anwendungen haben nichts miteinander zu tun, abgesehen von der geteilten API. Sie können so gut wie jede der beiden Anwendungen durch andere Technologien ersetzen und alles ist in Ordnung, solange die API respektiert wird.
Wir lieben diesen Ansatz, es gibt nichts daran auszusetzen, und dies ist kein Artikel, der diesen Ansatz kritisiert.
Warum also über einen anderen Ansatz sprechen? Django bietet bereits eine Vielzahl von Funktionen wie Sicherheit und Benutzerverwaltung. Wir wollen diese bereits etablierte Arbeit nicht in React wiederholen.
Dies erfordert einen anderen, integrierten Ansatz, der es uns erlaubt, Django-Funktionen zu nutzen und gleichzeitig die Interaktivität und Großartigkeit von React zu nutzen.
Die Grundidee ist gar nicht so abwegig, sie ist nicht einmal neu. Wir erweitern einfach eine Django-Vorlage mit Javascript, um ihr Interaktivität zu verleihen.
Das war's.
Es ist im Grunde dasselbe, als hätte man ein Skript-Tag in seiner Vorlage, das beim Laden eine Meldung anzeigt, die „Hallo Welt“ sagt, nur dass statt „Hallo Welt“ eine komplette Single-Page-App geladen wird. Das ist dasselbe, was Django-Entwickler seit den Anfängen von Django gemacht haben. Der einzige Unterschied ist, dass wir jetzt Webpack verwenden, um unser Deployment in Django zu vereinfachen (verkomplizieren?).
Beim Erstellen des Produktions-Builds verwendet Webpack den Javascript App-Einstiegspunkt in der Vorlage und den Javascript App-Quelle, um eine Django-Vorlage zu generieren und das Laden der Assets zu übernehmen.
Die Einstiegspunkt-Vorlage und die Assets werden dort gespeichert, wo Django sie finden kann und werden zusammen mit der Django-Anwendung bereitgestellt. Das heißt, wenn Django die Seite ausliefert, wird die JavaScript-Anwendung im Browser ausgeführt.
Bei der JavaScript-Anwendungsvorlage ist zu beachten, dass es sich auch um eine Django-Vorlage handelt. Sie können darin sowohl Django-spezifischen Code als auch solchen für Webpack einfügen. Webpack wird den Django-Code ignorieren und wenn Django ihn in die Finger bekommt, ist der Webpack-Code bereits verarbeitet.
Während der Entwicklung vereinfacht sich der Prozess etwas, da wir keine Assets mehr generieren und bereitstellen. Stattdessen verwenden wir den Webpack Dev-Server, um sie aus dem Speicher bereitzustellen. Das einzige, was noch im Dateisystem gespeichert werden muss, ist die Django-Vorlage.
Dies ermöglicht es uns, die Funktionalität des Webpack Dev-Servers, wie z.B. Hot-Reloading, weiterhin zu nutzen, während wir unsere Javascript-Anwendung von Django aus ausführen.
Wir brauchen nur eine einfache App mit einer Vorlage, das die Einstiegspunkt-Vorlage erweitert, da wir unsere React-App über diese Django-Vorlage laden werden.
Webpack ist unsere besondere Sauce, mit der alles funktioniert. Webpack ist ein Frontend-Bundler, der alle Abhängigkeiten kombiniert und ein auslieferbares Bundle bereitstellt. So können wir ein komplexes Frontend bauen und Webpack sorgt dafür, dass alles funktioniert, wenn wir es einsetzen. Webpack sorgt dafür, dass alle unsere Abhängigkeiten korrekt geladen und injiziert werden.
Die erste Aufgabe besteht darin, das Webpack-Ausgabeverzeichnis für statische Dateien festzulegen. Dies ist der Ordner, in dem Webpack all diese Abhängigkeiten speichern wird. Für unser aktuelles Projekt muss dies ein Ort sein, den Django finden kann. Da unser Frontend-Ordner auf der gleichen Ebene wie die Django-App liegt, können wir ihn static
nennen und das war's.
Jede Anwendung braucht einen Einstiegspunkt, an dem sie gestartet wird. Webpack erlaubt es uns, diesen Einstiegspunkt so zu setzen, wie wir wollen. In unserem Fall wollen wir, dass dieser Einstiegspunkt eine Django-Vorlage ist.
Der Webpack Dev-Server ist ein Tool, das uns schnellen In-Memory-Zugriff auf Assets und Live-Reloading ermöglicht. Er ist verantwortlich für die Injektion aller benötigten Dinge, wenn wir einen Entwicklungs-Build ausführen. In unserem Fall, da wir unseren Einstiegspunkt geändert haben und unsere Entwicklung in Django läuft, müssen wir auch die Konfiguration des Dev-Servers aktualisieren.
Normalerweise wird alles im Speicher gehalten, aber für dieses Szenario wollen wir, dass der Einstiegspunkt gespeichert wird, damit Django darauf zugreifen kann.
Sowohl für die Produktions- als auch für die Entwicklungseinstiegspunkte können wir das HtmlWebpackPlugin
verwenden.
HtmlWebpackPlugin erstellt den Einstiegspunkt für unsere SPA-Anwendung. In einem rein node-basierten Setup würde dies die HTML-Datei generieren, die zusammen mit den statischen Assets von einem Webserver an den Client geliefert wird. Wir haben die Ausgabe der HTML-Datei des Einstiegspunkts in einen Django-Vorlagenordner geändert.
Das HtmlWebpackPlugin verfügt über eine eigene HTML-Vorlage, die wir Eingabe-Vorlage nennen, um Verwechslungen mit der Ausgabe-Vorlage oder Django-Vorlage (die wir erstellen werden) zu vermeiden. Die Eingabe-Vorlage kann überall definiert werden, aber wenn du das Projekt zum Beispiel mit Create React App (CRA) gebootet hast, befindet es sich in der <javascript app root>/public/index.html
.
React basiert, wie die meisten Frontend-Frameworks, auf einer Reihe von Node-Paketen, die über einen Paketmanager verwaltet werden, heutzutage typischerweise npm oder yarn. Sie können den React-Ordner überall anlegen, aber wir haben uns dafür entschieden, ihn in einem Unterverzeichnis der Django-Anwendung zu erstellen.
Wenn du in letzter Zeit eine React-Anwendung erstellt hast, sind die Chancen groß, dass du Create React App (CRA) verwendet hast. CRA gibt dir eine Reihe von vernünftigen Standardeinstellungen, die unter den meisten Umständen gut funktionieren werden. Das ist großartig für normale Projekte, weil man sich nicht um die zusätzliche Konfiguration kümmern muss und jedes Mal, wenn CRA aktualisiert wird, werden diese Einstellungen auch aktualisiert.
Der Preis für diese Vereinfachung ist jedoch die Anpassungsfähigkeit. CRA gibt dir keinen Zugriff auf Webpack, und wie oben erklärt, ist die Webpack-Konfiguration zentral für das, was wir erreichen wollen. Wenn du also mit React baust, hast du ein paar Optionen, die dir Zugang zu Webpack-Konfiguration geben werden.
Es gibt Plugins, die CRA erweitern und Zugriff auf die Webpack-Konfiguration ermöglichen. Aber zum Zeitpunkt des Schreibens haben die meisten nicht die neueste Version von CRA unterstützt.
Die React-Entwickler schlagen vor, dass man, wenn man Änderungen an der Webpack-Konfiguration in CRA vornehmen möchte, das CRA-Projekt forkt und seine Änderungen dort aktualisiert. Sie können dann das geforkte CRA verwenden, um Ihre Anwendung zu erstellen. Für eine einfache Anwendung ist das total übertrieben.
Wenn du mehrere Anwendungen erstellst, die alle die gleichen Änderungen benötigen, würde ich dir raten, CRA zu forken.
Wie bereits erwähnt, bietet CRA vernünftige Standardeinstellungen und verbirgt einen Großteil der Komplexität von React.
Auswerfen bedeutet, alles versteckte wieder hervorzuholen. Wenn du eine React App auswirfst, sagst du ihr, dass du nun alles übernimmst, alle Konfigurationen, die gesamte Paketverwaltung, alles! Das gibt dir Zugriff auf alle Konfigurationsdateien, aber du bist jetzt verantwortlich für Updates und jegliche Probleme mit der Konfiguration. Das Auswerfen kann nicht rückgängig gemacht werden.
Wenn du willst, kannst du CRA auch ganz weglassen.
Du kannst React-Apps von Grund auf neu erstellen, ich spreche von leerem Verzeichnis, yarn init
,yarn add React
. Es ist ein bisschen mehr Arbeit, aber es hat den Vorteil, dass man nur die Konfiguration hat, die man will. Das ist eine spaßige Übung, die ich aber nicht empfehle, wenn Sie eine Deadline haben.
Jetzt können wir also eine React-Anwendung mit der von Webpack generierten Django-Vorlage ausführen, aber was ist, wenn unsere Anwendung mehrere Seiten unterstützen muss?
Um zu unterscheiden, auf welcher Seite man sich befindet, gibt es mehrere Lösungen:
Sowohl die Verwendung des React-Routers als auch die Übergabe von Seitendaten sind recht einfach zu implementieren, sodass beide Ansätze akzeptabel sind. Die Verwendung mehrerer Django-Templates hingegen ist zwar leistungsfähiger, aber auch komplizierter und für kleine Projekte wahrscheinlich zu aufwendig.
Sobald alles eingerichtet ist, haben Sie eine Anwendung mit enger Integration zwischen Django und React. Die Werkzeuge für Front-End-Entwickler werden wie erwartet funktionieren und die Auslieferung sollte dir deine Django-Anwendung erledigen, die React lädt, wenn sie angezeigt wird.
Das war’s eigentlich schon. Wir haben ein Repo mit dem Code, den Sie sich ansehen können, und Sie können ihn gerne forken und damit herumspielen.