Nx ist eine notwendige Voraussetzung. Die meisten Angular-Monorepos enthalten nur Frontend-Code. Um ein Full-Stack-Monorepo mit NestJS in einer bestehenden Angular-Umgebung zu konfigurieren, installieren Sie das Nest-Schematic und erstellen Sie ein neues Projekt innerhalb des Nx-Arbeitsbereichs:
$ npm i -D @nrwl/nest
$ npx nx g @nrwl/nest:application apps/your-api
Ein wesentliches Konzept bei der Arbeit mit Monorepos ist die Verwendung von Git-Submodulen. Git-Submodule helfen dabei, Code zwischen mehreren Repositories zu teilen und gleichzeitig die Commits getrennt zu halten. Während Frontend-Entwickler möglicherweise nur mit dem Frontend-Repository arbeiten, bevorzugen Full-Stack-Entwickler den Zugriff auf den gesamten Code. Git-Submodule bieten auch eine bequeme Möglichkeit, bestehende Projekte zusammenzuführen.
Die Struktur eines Monorepos, wie im Beispiel des LemonMart-Servers, lässt sich leicht erkennen: Es gibt drei Hauptordner:
Der Ordner bin enthält Hilfsskripte oder Tools, der Ordner web-app stellt das Frontend dar, und der Ordner server enthält den Backend-Code. In unserem Fall stellt der Ordner web-app das Projekt von Lemon-Mart dar. Statt den Code aus dem bestehenden Projekt zu kopieren, nutzen wir Git-Submodule, um zwei Repositories miteinander zu verknüpfen.
Die Datei package.json enthält Skripte, die beim Initialisieren, Aktualisieren und Bereinigen der Git-Submodule helfen. Ein nützliches Beispiel ist das Skript modules:update, mit dem Sie die neueste Version der Web-App abrufen können. Ich empfehle, die folgenden Aktionen auf der Version von LemonMart-Server auszuführen, die Sie von GitHub geklont haben. Falls Sie dies noch nicht getan haben, müssen Sie ein neues Projekt erstellen und npm init -y ausführen, um den Start zu erleichtern.
Um den web-app Ordner mit Ihrem Projekt zu initialisieren:
-
Aktualisieren Sie
webAppGitUrlmit der URL Ihres eigenen Projekts. -
Führen Sie
webapp:cleanaus, um den bestehendenweb-appOrdner zu entfernen. -
Führen Sie schließlich den Befehl
webapp:initaus, um Ihr Projekt imweb-appOrdner zu initialisieren:
$ npm run webapp:init
Ab sofort können Sie den Befehl modules:update verwenden, um den Code im Submodul zu aktualisieren. Um die Submodule nach dem Klonen des Repositories in einer anderen Umgebung zu ziehen, verwenden Sie npm modules:init. Wenn Sie die Umgebung zurücksetzen und neu starten müssen, führen Sie webapp:clean aus, um den Cache von Git zu bereinigen und den Ordner zu entfernen. Beachten Sie, dass Sie mehrere Submodule in Ihrem Repository haben können. Der Befehl modules:update aktualisiert alle Submodule gleichzeitig.
Ihr Webanwendungscode befindet sich nun im Ordner web-app. Außerdem sollten Sie beide Projekte im SOURCE CONTROL-Bereich von VS Code sehen können. Dies ermöglicht es, Git-Operationen für jedes Repository unabhängig durchzuführen. Sollte es zu Problemen mit einem Submodul kommen, wechseln Sie einfach in das Submodul-Verzeichnis, führen Sie git pull aus und dann git checkout main, um den Hauptzweig wiederherzustellen. Auf diese Weise können Sie jeden Branch Ihres Projekts auschecken und PRs einreichen.
Ein weiterer Vorteil der Verwendung von Git-Submodulen liegt in der Möglichkeit, sicherzustellen, dass Frontend und Backend im selben CI-Pipeline-Prozess zusammenarbeiten. Der config.yml-File von CircleCI implementiert zwei Jobs, die Teil des Workflows sind:
Die Pipeline überprüft den Code, stellt die Sicherheit der verwendeten Pakete mit audit-ci sicher, installiert die Abhängigkeiten, prüft auf Styling- und Linting-Fehler, führt Tests aus und kontrolliert die Codeabdeckung. Die Testbefehle bauen den Servercode, der im dist-Ordner gespeichert ist. Im letzten Schritt wird der dist-Ordner in den Arbeitsbereich verschoben, um ihn später zu verwenden. Die CI-Pipeline baut sowohl den Server als auch die Web-App parallel und ermöglicht es, den Deploy-Job auszuführen, wenn die Jobs im Hauptzweig erfolgreich sind.
Ein wichtiger Aspekt der Full-Stack-Entwicklung ist das frühe und sorgfältige Design der APIs. Sowohl das Frontend- als auch das Backend-Team sollten sich frühzeitig auf die wichtigsten Datenentitäten und deren Struktur einigen. Dies erleichtert nicht nur die Zusammenarbeit zwischen den Teams, sondern sorgt auch dafür, dass sich beide Seiten an einem gemeinsamen Vertrag orientieren. In der Architektur von Router-first, die hier thematisiert wird, ist es sinnvoll, TypeScript-Interfaces zu verwenden, um die Architektur der App schnell zu skizzieren. Ein wenig frühes Design sichert die Integration der Komponenten und stellt sicher, dass diese im Laufe der Entwicklung nicht auseinanderfallen.
Im Zusammenhang mit API-Design ist es entscheidend, von Anfang an klare Ziele zu setzen. Ein gutes API-Design trägt dazu bei, die Datenübertragung zwischen Client und Server zu minimieren, bewährte Designmuster wie die Paginierung zu verwenden und die Geschäftslogik möglichst vollständig im Backend zu implementieren. Die Frontend-Logik sollte sich auf die Präsentation konzentrieren. Jeder if-Befehl, der im Frontend implementiert wird, sollte auch im Backend verifiziert werden, um Inkonsistenzen zu vermeiden.
Wichtig ist es, beim Design von APIs darauf zu achten, keine Datenbank-Schlüssel oder Fremdschlüsselbeziehungen offenzulegen und Endpunkte von Anfang an zu versionieren. Ein stateless Design sowohl im Backend als auch im Frontend ist von großer Bedeutung, um eine nahtlose Skalierung der Webanwendung in Cloud-Umgebungen zu ermöglichen. Sessions sind in skalierbaren Systemen problematisch, da sie viel Speicher benötigen. Wenn Sie an einem Full-Stack-Projekt arbeiten, sollten Sie darauf achten, dass Sie keine Experimente im Produktionscode durchführen, da Designfehler in APIs tiefgreifende Auswirkungen auf die gesamte Anwendung haben können. Ein Proof of Concept ist eine ideale Möglichkeit, neue Ideen zu testen, bevor sie in ein produktives System integriert werden.
Die Nutzung von OpenAPI für REST und von GraphQL-Schemas zur Dokumentation des API-Designs ermöglicht es den Teammitgliedern, die Absichten hinter der API klar zu kommunizieren und stellt sicher, dass der Entwurf auch später als interaktive Referenz genutzt werden kann.
Wie sorgt man für zuverlässige und schnelle Software-Deployments mit CI/CD und automatisierten Tests?
„Aber es funktioniert doch auf meiner Maschine!“ – diese Ausrede von Entwicklern, wenn ihre Software unerwartet versagt, verdeutlicht ein bekanntes Problem in der Softwareentwicklung: Die Diskrepanz zwischen Entwicklungs- und Produktionsumgebung. Um dieses Problem zu überwinden und qualitativ hochwertige Software verlässlich und schnell auszuliefern, ist Continuous Integration und Continuous Deployment (CI/CD) unerlässlich.
Im Enterprise-Umfeld ist es essenziell, dass Code nicht nur geschrieben, sondern auch automatisiert geprüft, gebaut und verteilt wird – möglichst häufig und ohne Qualitätseinbußen. Hierzu werden umfangreiche automatisierte Tests benötigt, welche sowohl Unit- als auch End-to-End-Tests umfassen. Diese Tests sind das Rückgrat der CI/CD-Pipeline, denn sie garantieren, dass neue Änderungen keine Fehler oder Regressionen in bereits funktionierenden Teilen verursachen. Werkzeuge wie Cypress für E2E-Tests und Unit-Test-Frameworks ermöglichen es, diese Qualitätssicherung effizient zu implementieren.
Ein weiterer wichtiger Baustein sind moderne DevOps-Praktiken, wie Infrastructure as Code (IaC). Diese ermöglichen es, Infrastrukturkonfigurationen und Deployment-Prozesse als Code zu verwalten, wodurch sich Builds und Deployments reproduzierbar und automatisiert auf verschiedenen Umgebungen und Cloud-Anbietern ausführen lassen. Die Verwendung von Containern, z. B. Docker, schafft eine einheitliche Laufzeitumgebung, die „es funktioniert auf meiner Maschine“ in „es funktioniert überall“ verwandelt. Die Containerisierung macht Anwendungen portabel und unterstützt das einfache Skalieren in Cloud-Umgebungen.
CI/CD-Pipelines wie jene mit CircleCI oder Jenkins orchestrieren diesen Prozess, indem sie Quellcodeänderungen automatisch erkennen, Tests ausführen, Anwendungen bauen und diese in produktive Umgebungen ausrollen. Dabei sind parallele Builds, automatisierte Tests und detaillierte Code-Coverage-Berichte wichtige Merkmale, um schnelle und verlässliche Release-Zyklen zu gewährleisten. So wird der Druck, „schnell zu liefern“, mit der Notwendigkeit hoher Qualität vereinbart – ein zentraler Aspekt im professionellen Softwareengineering.
Das Vermeiden von manuellen Deployment-Schritten minimiert menschliche Fehler und beschleunigt den Release-Prozess. Dabei ist es wichtig, nicht zu stark auf einzelne CI/CD-Anbieter festgelegt zu sein, sondern durch flexible und portable Konfigurationen, wie Docker-Container, die eigenen Kenntnisse und Werkzeuge für verschiedene Plattformen nutzbar zu halten.
Zu den technischen Voraussetzungen gehören neben Docker und einem CI-Server (CircleCI, Jenkins, Azure DevOps etc.) oft auch Dienste wie Firebase oder Vercel für Hosting und Coveralls für Code-Coverage-Reporting. Das Zusammenspiel dieser Werkzeuge schafft eine umfassende Umgebung für modernes, agiles und zuverlässiges Software-Deployment.
Zusätzlich zur technischen Implementierung ist das Verständnis für Teststrategien, die korrekte Gestaltung von Pipelines und die Notwendigkeit kontinuierlicher Verbesserung entscheidend. Die Softwareentwicklung in Unternehmen folgt oft strengen Qualitätssicherungsprozessen und „Quality Gates“, um sicherzustellen, dass nur geprüfter Code in produktive Systeme gelangt. Automatisierte Tests müssen so gestaltet sein, dass sie schnell und präzise Fehler erkennen, ohne den Entwicklerfluss durch zu lange Laufzeiten zu behindern.
Das Einführen von CI/CD bedeutet auch eine kulturelle Veränderung innerhalb von Teams, die Zusammenarbeit und Kommunikation verbessern muss. Entwickler, Tester und Betrieb müssen ihre Prozesse eng verzahnen, um schnell auf Probleme reagieren und Software iterativ verbessern zu können.
Wichtig ist auch die Balance zwischen Geschwindigkeit und Stabilität. „Move fast and break things“ mag in Startup-Umgebungen funktionieren, in Enterprise-Projekten ist jedoch eine kontrollierte, risikoarme Auslieferung unabdingbar. Dies erfordert sorgfältig entwickelte Automatisierungsprozesse, robuste Tests und eine Infrastruktur, die skalierbar und wartbar ist.
Endlich sind Versionsverwaltung und automatisierte Code-Reviews integraler Bestandteil jeder CI/CD-Strategie. Sie stellen sicher, dass Änderungen nachvollziehbar bleiben und Qualitätsstandards eingehalten werden. Dies unterstützt eine nachhaltige Entwicklung, bei der Fehler frühzeitig entdeckt und behoben werden können.
Neben den technischen Aspekten sollten Leser auch die Wichtigkeit von Monitoring und Feedback-Schleifen verstehen. Nach dem Deployment ist die Überwachung der Anwendung im produktiven Betrieb entscheidend, um Performance, Verfügbarkeit und Fehlerzustände frühzeitig zu erkennen. Dies ermöglicht schnelle Reaktionen und kontinuierliche Verbesserung.
Die erfolgreiche Implementierung von CI/CD und automatisierten Tests ist somit ein komplexes Zusammenspiel von Technologien, Prozessen und Kultur. Nur so lässt sich die Vision einer agilen, zuverlässigen und skalierbaren Softwareentwicklung im Enterprise-Kontext realisieren.
Wie die digitale Welt die emotionale und physiologische Regulierung von Kindern beeinflusst und wie Eltern unterstützen können
Welche typografischen Prinzipien sind entscheidend für das Design eines professionellen Buchcovers?
Was passierte mit den Arbeitern, die die Pyramiden von Gizeh erbauten?
Was ist das Erbe der amerikanischen Musik und wie beeinflusst es die Kultur der USA?

Deutsch
Francais
Nederlands
Svenska
Norsk
Dansk
Suomi
Espanol
Italiano
Portugues
Magyar
Polski
Cestina
Русский