Introducción: ¿qué es un monorepositorio y por qué lo necesita un desarrollador PHP?
El desarrollo de grandes proyectos PHP a menudo se enfrenta al problema de la organización del código. El enfoque clásico con repositorios separados para cada componente (bibliotecas, microservicios, frontend) conduce a la fragmentación, duplicación de dependencias y dificultades en la refactorización. Una alternativa es el monorepositorio: un repositorio único que contiene todos los proyectos y paquetes relacionados.
En este artículo, analizaremos en la práctica cómo organizar un monorepositorio para un proyecto PHP. Aprenderá a configurar Composer, estructurar carpetas, gestionar dependencias y organizar CI/CD. El artículo está dirigido a desarrolladores PHP de nivel intermedio familiarizados con los conceptos básicos de Git y Composer.
Principales ventajas de un monorepositorio:
- Historial de cambios unificado y commits atómicos
- Facilidad de refactorización de dependencias comunes
- Herramientas y configuraciones unificadas
- Simplificación de CI/CD a través de un pipeline único
Estructura del monorepositorio: eligiendo la arquitectura correcta
El elemento clave de un monorepositorio exitoso es una estructura de carpetas bien pensada. Para proyectos PHP, recomendamos la siguiente plantilla, basada en la separación en paquetes y aplicaciones:
monorepo/├── apps/ # Aplicaciones listas (sitios web, API, scripts de consola)│ ├── api/ # REST API en Slim o Laravel│ │ ├── public/│ │ ├── src/│ │ └── composer.json│ └── admin/ # Panel de administración│ ├── public/│ ├── src/│ └── composer.json├── packages/ # Paquetes PHP reutilizables (bibliotecas)│ ├── core/ # Núcleo del sistema: clases base, excepciones│ │ ├── src/│ │ └── composer.json│ ├── users/ # Paquete para gestión de usuarios│ │ ├── src/│ │ └── composer.json│ └── payments/ # Paquete de pagos│ ├── src/│ └── composer.json├── tools/ # Scripts de compilación y auxiliares├── tests/ # Pruebas de integración y E2E para todo el proyecto├── composer.json # Manifiesto raíz (normalmente "type": "project")├── composer.lock├── phpstan.neon├── phpunit.xml.dist└── .gitignoreCada paquete en packages/ es una biblioteca Composer independiente con su propio composer.json. Las aplicaciones en apps/ conectan estos paquetes como dependencias locales. Esta estructura permite:
- Aislar la lógica y probar los paquetes de forma independiente
- Usar tipado estricto y autocarga PSR-4
- Reutilizar código entre diferentes aplicaciones sin copiarlo
Configuración de Composer para trabajar con un monorepositorio
Composer es la herramienta principal para la gestión de dependencias en PHP. Para trabajar con un monorepositorio, usamos dos mecanismos clave: rutas locales (path) y manifiesto raíz.
Paso 1: composer.json raíz
En la raíz del proyecto, creamos un manifiesto mínimo que define que esto es un monorepositorio:
{ "name": "mycompany/monorepo", "type": "project", "require": { "php": "^8.1" }, "autoload": { "psr-4": { "MyCompany\\\\": "packages/" } }, "scripts": { "test": "phpunit", "phpstan": "phpstan analyse" }}Paso 2: Dependencias locales en los paquetes
Cada paquete en packages/users/ debe tener su propio composer.json. Por ejemplo:
{ "name": "mycompany/users", "type": "library", "require": { "php": "^8.1", "mycompany/core": "*" }, "autoload": { "psr-4": { "MyCompany\\\\Users\\\\": "src/" } }}