Monorepositório com PHP: organização de código para projetos escaláveis
No desenvolvimento PHP moderno, o gerenciamento de código torna-se criticamente importante à medida que o projeto cresce. A abordagem tradicional com múltiplos repositórios separados (polirepositório) frequentemente leva a problemas de sincronização, duplicação de dependências e complexidades durante a refatoração. A alternativa — o monorepositório (Monorepo), onde todo o código, incluindo bibliotecas, utilitários e aplicações, é armazenado em um único repositório Git. Neste artigo, vamos analisar como organizar um monorepositório em PHP, usando Composer, Git e ferramentas modernas.
O que é um monorepositório e por que ele é necessário em PHP?
Um monorepositório é um repositório único que contém vários projetos, pacotes ou módulos que podem estar logicamente relacionados. Para um desenvolvedor PHP, isso significa que o núcleo do framework, o serviço de API, o painel administrativo e as bibliotecas comuns estão em uma única pasta.
Vantagens do monorepositório:
- Versionamento unificado: Todas as alterações são commitadas atomicamente — uma correção em uma biblioteca é imediatamente acompanhada pela atualização do código que a utiliza.
- Simplificação da refatoração: Você pode alterar a interface de um pacote e atualizar imediatamente todas as dependências dentro de um único pull request.
- Padronização de ferramentas: Um único arquivo
composer.jsonpara a raiz, regras unificadas de linting e testes. - Redução de duplicação: Código comum (por exemplo, DTOs, helpers) não precisa ser publicado no Packagist — ele está disponível diretamente.
No entanto, o monorepositório exige disciplina: sem uma estrutura clara, ele se transforma em um "depósito de lixo". A chave para o sucesso é a organização correta usando o autoload do Composer e submódulos Git ou ferramentas especializadas como monorepo-builder.
Estrutura de um monorepositório em PHP
Vamos considerar uma estrutura típica para um projeto PHP que possui várias bibliotecas e uma aplicação. O diretório raiz se parece com isto:
my-monorepo/├── packages/│ ├── core/ # Biblioteca base (núcleo)│ │ ├── src/│ │ │ └── CoreClass.php│ │ └── composer.json│ ├── logger/ # Logging│ │ ├── src/│ │ └── composer.json│ └── api/ # Pacote de API (pode ser uma aplicação separada)│ ├── src/│ │ └── Controllers/│ └── composer.json├── apps/│ └── web/ # Aplicação web (Laravel/Symfony)│ ├── public/│ ├── src/│ └── composer.json├── composer.json # composer.json raiz (meta-pacote)├── phpunit.xml.dist└── .gitignorePrincípios de organização:
- Todos os pacotes estão em
packages/. Cada pacote tem seu própriocomposer.jsoncom um nome único (por exemplo,mycompany/core). - As aplicações (frontend, admin, API) ficam em
apps/. Elas podem usar os pacotes depackages/como dependências locais. - O
composer.jsonraiz serve para configuração global (autoload, scripts).
Configuração do Composer para trabalhar com monorepositório
Para que o autoload do PHP funcione sem publicar os pacotes no Packagist, usamos repositórios path. Adicione o seguinte bloco ao composer.json raiz:
{ "name": "mycompany/monorepo", "require": { "mycompany/core": "*", "mycompany/logger": "*" }, "repositories": [ { "type": "path", "url": "packages/*" } ], "autoload": { "psr-4": { "MyCompany\\\\": "packages/" } }, "scripts": { "test": "phpunit" }}Agora, ao executar composer install, o Comp