Onboarding in React leicht gemacht: Unser neues React-Template
Wir haben unser React-Template „Die Chuck Norris Challange“ komplett neu aufgesetzt. Das Template nutzen wir maßgeblich für unser internes OnBoarding für neue Mitarbeiter im Frontend oder auch als Boilerplate für neue Projekte. In dem Template sind viele Best Practices und Erfahrungen vergangener Projekte miteingeflossen, die wir in diesem Artikel vorstellen möchten:
Next.js: Warum wir auf Server-Side-Rendering gewechselt sind
Next.js ist ein Open-Source-Framework für das serverseitige Rendern von React-Anwendungen. Es wurde entwickelt, um die Entwicklung von React-basierten Webanwendungen zu vereinfachen, insbesondere solche, die auf dem Server gerendert werden müssen.
Traditionell wird React im Client-Browser gerendert, was bedeutet, dass der Browser den JavaScript-Code herunterlädt und dann die Komponenten der Anwendung rendert. Dies kann zu einer Verzögerung beim Laden der Seite führen, da der Benutzer warten muss, bis der Code heruntergeladen und der Browser die Seite gerendert hat.
Next.js ermöglicht es Entwicklern, React-Komponenten sowohl auf dem Server als auch im Browser zu rendern. Dies hat den Vorteil, dass der Benutzer sofort eine vollständig gerenderte Seite angezeigt bekommt, während der JavaScript-Code im Hintergrund geladen wird.
In der Vergangenheit haben wir eher selten auf Server-Side-Rendering gesetzt. Meist nur, wenn es für SEO-Zwecke notwendig war. Mittlerweile hat sich aber viel getan. Die zwei größten Punkte sind unserer Ansicht, dass nun das Deployment und Hosting bei viele Lösungen extra eine Next.js bzw. SSR-Option anbieten. Beispielsweise wird bei Firebase bzw. Google Cloud eine Next.js Anwendung genauso einfach deployed und gehostet, wie eine herkömmliche Client-Side WebApp. In der firebase.json muss lediglich noch die Region richtig gesetzt werden:
Der Befehl „firebase deploy“ erkennt automatisch, dass es sich um eine Next.js Konfiguration handelt. Für uns heißt das, dass wir uns nicht mehr um einen Next.js Server kümmern müssen und das Hosting weitgehend out-of-the-box läuft, dies war sonst meist ein Grund für Client Side Rendering.
Der zweite große Punkt ist, dass in der neuen offiziellen React-Doku keine Wort mehr über „create react app“ verschwendet wird und das Initialisieren eines neuen Projektes nur noch mit SSR wie z.B. Next.js, Remix oder Gatsby empfohlen wird. Der Befehl „create react app“ war der offizielle Standard von React, um ein neues Projekt aufzusetzen. Dass dieser Weg nun nicht mehr in der Doku vorkommt ist für uns ein Signal, dass hier langfristig wahrscheinlich keine Energie und Wartungsarbeit mehr hineinfließen wird.
Ordnerstruktur Domain Driven
Eine gute Ordnerstruktur für eine Projekt zu finden ist sehr individuell und subjektiv. Darum wollen wir in unserem Template nur einen Vorschlag liefern, wie ein Projekt gut organisiert sein könnte. Wichtig ist auch: eine Ordnerstruktur lebt und sollte auch immer zur wachsenden Projektgröße, den Entwicklern und den Anforderungen passen. Renamings und Umstrukturierungen sind genauso wichtig wie Refactoring im Code selbst.
Maßgeblich gibt es jedoch zwei Hauptansätze, wie man ein Frontendprojekt strukturieren könnte, die anhand von Beispielen schnell erklärt sind:
Anwendungsgetrieben:
- src
- components
- tsx
- tsx
- tsx
- …
- models
- ts
- ts
- …
- state
- ts
- …
- tests
- test.ts
- …
- components
Domain Driven:
- src
- app
- components
- model
- theming
- auth
- components
- context
- model
- jokes
- api
- components
- model
- randomColor
- components
- model
- state
- tests
- app
Die Erfahrung bei uns hat gezeigt, dass für die meisten Projekte die Gliederung nach der fachlichen Domäne bzw. Domain Driven die bessere war, da man sich auch bei wachsender Projektgröße noch gut zurecht findet. Für strenge Richtlinien bei der Ordnerstruktur haben wir uns aber dagegen entschieden, da es wichtig ist, dass die Struktur zum Projekt und den Entwicklern passt. Unser maßgebendes Kriterium ist hier stets, wie schnell man sich als neuer Entwickler im Projekt zurecht findet.
Material-UI
Material ist ein Designrichtlinie bzw. ein Styleguide von Google. Die neueste Auflage ist inzwischen die Version 3, wobei sich die aktuell nicht recht durchzusetzen scheint. Die Vorgängerversion ist dafür umso etablierter. Ob von Google selbst oder von zahlreichen anderen App und WebApp Entwicklern – Material Oberflächen sind sehr stark in Verwendung und die Benutzer haben sich an die Ein- und Ausgabekomponenten bestens gewöhnt. Material beschreibt neben Farben, Abständen usw. auch das Aussehen und Verhalten von UI-Komponenten, wie z.B. Buttons, Textfelder und Dropdowns.
Diese Spezifikation von Komponenten wird von der Library Material-UI für React umgesetzt. Neben den fertigen Komponenten bietet Material-UI eine hervorragende API um Buttons etc. auch individuell anzupassen, falls nötig. Die große Beliebtheit von Material-UI beweisen die 88000 Github-Stars. Wir bei der innFactory nutzen Material-UI bereits seit 6 Jahren und sind von der Stabilität und guten Migrierbarkeit auf neue Versionen und der Weiterentwicklung der Library begeistert.
Statemanagement mit Recoil
Offiziell ist das Statemanagement Framework Recoil das direkt von Facebook/Meta für React entwickelt wurde, noch in der Betaphase. Aufgrund der schnell anwachsenden Community und der guten Erfahrungen aus unseren eigenen Tests, setzen wir aber schon länger auch produktiv auf Recoil. Bei größeren Projekten konnten wir die Seiteneffekte gegenüber zu Redux deutlich reduzieren, währen die Übersichtlichkeit und Wartbarkeit gestiegen ist. Bei richtig großen Projekten bleibt aber das Statemanagement trotzdem komplex, dies wird auch kein Framework der Welt lösen können.
Der für uns größte Vorteil an Recoil ist, dass am Anfang bei einem kleinen Projekt sehr leichtgewichtig ist. Sobald das Projekt wächst, ist aber Recoil auch flexibel und stark genug um allen Anforderungen gerecht zu werden und trotzdem bei guter Implementierung übersichtlich zu bleiben.
Authentifizierung mit Firebase Auth (Google Cloud)
Für das Benutzermanagement und Authentifizierung setzen wir auf etablierte Lösungen, wie z.B. Firebase Auth für kleinere Projekte oder Keycloak für speziellere Anforderungen. In unserem Demo Projekt haben wir die Integration zu Firebase Auth Implementiert und so abstrahiert, dass man später auch Keycloak als Auth-Provider verwenden bzw. recht einfach umbauen könnte.
Das Zusammenspiel mit Next.js gestaltete hier sich etwas schwieriger, konnte aber in unserem Beispielprojekt mit dem src/auth/context/AuthContext.ts gut gelöst werden. Falls man einen anderen Auth-Provider integrieren wollte, müsste man nur eine andere Implementierung des AuthContexts benötigen.
Formulare mit Formik und Yup
Auch als erfahrener Entwickler für WebFrontends bin ich doch jedes Mal erstaunt, wie aufwendig doch die Implementierung eines guten Formulars ist. Meist sind es nur ein paar Textfelder, wiederkehrend, und doch so unterschiedlich, dass man die Logik dahinter individuell abbilden muss.
Natürlich ist ein Formular keine Rocketsience. Trotzdem ist eine saubere Validierung, aussagekräftige Hinweise und Fehlermeldungen für den Benutzer entscheidend, um eine gute User Experience zu kreieren. Für diese Routineaufgabe hat sich bei uns längst ein Validierungs Framework wie z.B. Formik mit Yup etabliert. Anfangs wirken Formulare mit Formik etwas Overhead-lastig, doch schon das zweite Formular ist so gleichartig, dass sich durch den modularen Aufbau vieles wiederverwerten oder abwandeln lässt. Für die Validierung von E-Mail-, Passwort- und allen anderen Feldern bringt Yup einen Standardbaukasten mit, der aber zugleich auch höchst individualisierbar ist. So ist es ein Kinderspiel zum Beispiel die Eingabe einer 18-stelligen Seriennummer oder diverse Zahlenbereiche zu prüfen und dem Benutzer ein verständliches Feedback zu präsentieren.
Requests und Caching mit TanStack-Query (ehem. React-Query)
TanStack-Query ist eine Open-Source-Bibliothek für das Datenmanagement die für React, aber auch für Vue, Svelte und Solid zur Verfügung steht. Sie wurde entwickelt, um das Arbeiten mit asynchronen Daten, also Datenabrufen von APIs, zu vereinfachen und die Leistung und Reaktivität der Anwendung zu verbessern.
Sie übernimmt biespielsweise das Caching der Requests oder ermöglicht es den Ladezustand von Abfragen zu verfolgen. Bei Fehlerhaften Antworten von API-Aufrufen (z.B. wenn man in der Bahn kurz kein Internet hat) übernimmt TanStack das automatische refetchen.
Wer einmal diese Vielfalt an Funktionalität selbst implementiert hat, weiß, wie wertvoll eine solche Bibliothek ist. Bevor wir uns für TanStack-Query entschieden haben, haben wir auch den Konkurrenten SWR evaluiert. Bei SWR haben uns aber die wenigen Einstellmöglichkeiten (Stand 2022) in Bezug auf Caching nicht gereicht. Generell macht auf uns die Bibliothek von TanStack den ausgereifteren und durchdachteren Eindruck.
Wie das Ganze funktioniert, wird im Template mit der ChucknorrisAPI veranschaulicht. Die Komponente „RandomJoke.tsx“ verwendet die Bibliothek wie folgt:
Der Boolean „isLoading“ blendet bei True eine Ladeanimation ein. Sobald der Request vom Server fehlerfrei zurückgekommen ist, sind die Daten in der Variable „data“ zu finden und mit der Funktion „refetch“ kann den erneuten Aufruf manuell auslösen. TanStack-Query bietet einen Automatismus an, damit beim Erneuten Rendern der Seite oder der Selektierung des Browsertabs die Daten aktualisiert werden. Da uns hier die API aber immer einen neuen Zufallwitz zurückgibt und der erst manuell erneuert werden soll, wird dieser Mechanismus mit „refetchOnMount“ und „refetchOnWindowFucus“ ausgeschalten.
Fazit
Unser React-Template react-chuck-norris ist mit den besten Bibliotheken und Learnings ausgestattet, die wir in den vergangen Jahren eingesetzt haben. Dieses Setup ist nicht nur perfekt um neue Mitarbeiter in die Frontendentwicklung einzuführen, sondern eignet sich auch als Boilerplate für neue Projekte und Produktideen. Da das Repository wurde mit der MIT Lizenz veröffentlich und darf daher bedingungslos frei verwendet werden. Wir würden uns freuen, wenn wir dazu Feedback oder auch Verbesserungsvorschläge erhalten, denn dass Template soll stets weiterentwickelt und aktualisiert werden, damit es auch in Zukunft für unsere nächsten Herausforderungen im Webbereich ready ist.
Hier der Link zum Repository: