Introduction : qu'est-ce qu'un monorepo et pourquoi un développeur PHP en a-t-il besoin ?
Le développement de grands projets PHP est souvent confronté au problème de l'organisation du code. L'approche classique avec des dépôts séparés pour chaque composant (bibliothèques, microservices, frontend) entraîne une fragmentation, une duplication des dépendances et des difficultés lors du refactoring. Une alternative est le monorepo — un dépôt unique contenant tous les projets et paquets associés.
Dans cet article, nous allons voir en pratique comment organiser un monorepo pour un projet PHP. Vous apprendrez à configurer Composer, structurer les dossiers, gérer les dépendances et organiser le CI/CD. Cet article s'adresse aux développeurs PHP de niveau intermédiaire, familiers avec les bases de Git et Composer.
Les principaux avantages du monorepo :
- Historique unique des modifications et commits atomiques
- Simplicité du refactoring des dépendances communes
- Outils et configurations unifiés
- Simplification du CI/CD via un pipeline unique
Structure du monorepo : choisir la bonne architecture
L'élément clé d'un monorepo réussi est une structure de dossiers bien pensée. Pour les projets PHP, nous recommandons le modèle suivant, basé sur la séparation en paquets et applications :
monorepo/├── apps/ # Applications prêtes (sites web, API, scripts console)│ ├── api/ # API REST avec Slim ou Laravel│ │ ├── public/│ │ ├── src/│ │ └── composer.json│ └── admin/ # Panneau d'administration│ ├── public/│ ├── src/│ └── composer.json├── packages/ # Paquets PHP réutilisables (bibliothèques)│ ├── core/ # Cœur du système : classes de base, exceptions│ │ ├── src/│ │ └── composer.json│ ├── users/ # Paquet pour la gestion des utilisateurs│ │ ├── src/│ │ └── composer.json│ └── payments/ # Paquet de paiement│ ├── src/│ └── composer.json├── tools/ # Scripts de build et utilitaires├── tests/ # Tests d'intégration et E2E pour l'ensemble du projet├── composer.json # Manifeste racine (généralement "type": "project")├── composer.lock├── phpstan.neon├── phpunit.xml.dist└── .gitignoreChaque paquet dans packages/ est une bibliothèque Composer autonome avec son propre composer.json. Les applications dans apps/ connectent ces paquets comme dépendances locales. Cette structure permet :
- D'isoler la logique et de tester les paquets indépendamment
- D'utiliser un typage strict et un autoloading PSR-4
- De réutiliser le code entre différentes applications sans copie
Configuration de Composer pour travailler avec un monorepo
Composer est l'outil principal de gestion des dépendances en PHP. Pour travailler avec un monorepo, nous utilisons deux mécanismes clés : les chemins locaux (path) et le manifeste racine.
Étape 1 : composer.json racine
À la racine du projet, créez un manifeste minimal qui définit qu'il s'agit d'un monorepo :
{ "name": "mycompany/monorepo", "type": "project", "require": { "php": "^8.1" }, "autoload": { "psr-4": { "MyCompany\\\\": "packages/" } }, "scripts": { "test": "phpunit", "phpstan": "phpstan analyse" }}Étape 2 : Dépendances locales dans les paquets
Chaque paquet dans packages/users/ doit avoir son propre composer.json. Par exemple :
{ "name": "mycompany/users", "type": "library", "require": { "php": "^8.1", "mycompany/core": "*" }, "autoload": { "psr-4": { "MyCompany\\\\Users\\\\": "src/" } }}