Einleitung: Was ist ein Monorepository und warum braucht ein PHP-Entwickler es?
Die Entwicklung großer PHP-Projekte steht oft vor dem Problem der Code-Organisation. Der klassische Ansatz mit separaten Repositorys für jede Komponente (Bibliotheken, Microservices, Frontend) führt zu Fragmentierung, doppelten Abhängigkeiten und Komplexität beim Refactoring. Eine Alternative ist das Monorepository – ein einheitliches Repository, das alle zugehörigen Projekte und Pakete enthält.
In diesem Artikel werden wir in der Praxis durchgehen, wie man ein Monorepository für ein PHP-Projekt organisiert. Sie erfahren, wie Sie Composer einrichten, Ordner strukturieren, Abhängigkeiten verwalten und CI/CD organisieren. Der Artikel richtet sich an PHP-Entwickler mit mittleren Kenntnissen, die mit den Grundlagen von Git und Composer vertraut sind.
Die Hauptvorteile eines Monorepositorys:
- Einheitliche Änderungshistorie und atomare Commits
- Einfaches Refactoring gemeinsamer Abhängigkeiten
- Vereinheitlichte Tools und Konfigurationen
- Vereinfachung von CI/CD durch eine einheitliche Pipeline
Struktur des Monorepositorys: Die richtige Architektur wählen
Das Schlüsselelement eines erfolgreichen Monorepositorys ist eine durchdachte Ordnerstruktur. Für PHP-Projekte empfehlen wir folgendes Schema, das auf der Trennung in Pakete und Anwendungen basiert:
monorepo/├── apps/ # Fertige Anwendungen (Websites, APIs, Konsolenskripte)│ ├── api/ # REST API mit Slim oder Laravel│ │ ├── public/│ │ ├── src/│ │ └── composer.json│ └── admin/ # Administrationsoberfläche│ ├── public/│ ├── src/│ └── composer.json├── packages/ # Wiederverwendbare PHP-Pakete (Bibliotheken)│ ├── core/ # Systemkern: Basisklassen, Ausnahmen│ │ ├── src/│ │ └── composer.json│ ├── users/ # Paket für Benutzerverwaltung│ │ ├── src/│ │ └── composer.json│ └── payments/ # Zahlungspaket│ ├── src/│ └── composer.json├── tools/ # Build- und Hilfsskripte├── tests/ # Integrations- und E2E-Tests für das gesamte Projekt├── composer.json # Root-Manifest (normalerweise "type": "project")├── composer.lock├── phpstan.neon├── phpunit.xml.dist└── .gitignoreJedes Paket in packages/ ist eine eigenständige Composer-Bibliothek mit eigenem composer.json. Die Anwendungen in apps/ binden diese Pakete als lokale Abhängigkeiten ein. Diese Struktur ermöglicht:
- Isolierung der Logik und unabhängiges Testen der Pakete
- Verwendung strenger Typisierung und PSR-4-Autoloading
- Wiederverwendung von Code zwischen verschiedenen Anwendungen ohne Kopieren
Einrichtung von Composer für die Arbeit mit dem Monorepository
Composer ist das wichtigste Tool zur Verwaltung von Abhängigkeiten in PHP. Für die Arbeit mit einem Monorepository verwenden wir zwei Schlüsselmechanismen: lokale Pfade (path) und Root-Manifest.
Schritt 1: Root composer.json
Im Projektstamm erstellen wir ein minimales Manifest, das definiert, dass es sich um ein Monorepository handelt:
{ "name": "mycompany/monorepo", "type": "project", "require": { "php": "^8.1" }, "autoload": { "psr-4": { "MyCompany\\\\": "packages/" } }, "scripts": { "test": "phpunit", "phpstan": "phpstan analyse" }}Schritt 2: Lokale Abhängigkeiten in Paketen
Jedes Paket in packages/users/ muss seine eigene composer.json haben. Zum Beispiel:
{ "name": "mycompany/users", "type": "library", "require": { "php": "^8.1", "mycompany/core": "*" }, "autoload": { "psr-4": { "MyCompany\\\\Users\\\\": "src/" } }}\