Monorepositório com PHP: organização de código na prática

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Introdução: o que é um monorepositório e por que ele é necessário para um desenvolvedor PHP?

O desenvolvimento de grandes projetos PHP frequentemente enfrenta o problema de organização do código. A abordagem clássica com repositórios separados para cada componente (bibliotecas, microsserviços, frontend) leva à fragmentação, duplicação de dependências e dificuldades durante a refatoração. Uma alternativa é o monorepositório — um repositório único contendo todos os projetos e pacotes relacionados.

Neste artigo, vamos abordar na prática como organizar um monorepositório para um projeto PHP. Você aprenderá como configurar o Composer, estruturar pastas, gerenciar dependências e organizar CI/CD. O artigo é voltado para desenvolvedores PHP de nível intermediário, familiarizados com os fundamentos do Git e Composer.

Principais vantagens do monorepositório:

  • Histórico unificado de alterações e commits atômicos
  • Facilidade de refatoração de dependências compartilhadas
  • Ferramentas e configurações unificadas
  • Simplificação do CI/CD por meio de um pipeline único


Estrutura do monorepositório: escolhendo a arquitetura correta

O elemento-chave de um monorepositório bem-sucedido é uma estrutura de pastas bem planejada. Para projetos PHP, recomendamos o seguinte modelo, baseado na separação em pacotes e aplicações:



monorepo/├── apps/                   # Aplicações prontas (sites web, APIs, scripts de console)│   ├── api/                # REST API em Slim ou Laravel│   │   ├── public/│   │   ├── src/│   │   └── composer.json│   └── admin/              # Painel de administração│       ├── public/│       ├── src/│       └── composer.json├── packages/               # Pacotes PHP reutilizáveis (bibliotecas)│   ├── core/               # Núcleo do sistema: classes base, exceções│   │   ├── src/│   │   └── composer.json│   ├── users/              # Pacote para gerenciamento de usuários│   │   ├── src/│   │   └── composer.json│   └── payments/           # Pacote de pagamentos│       ├── src/│       └── composer.json├── tools/                  # Scripts de build e auxiliares├── tests/                  # Testes de integração e E2E para todo o projeto├── composer.json           # Manifesto raiz (geralmente "type": "project")├── composer.lock├── phpstan.neon├── phpunit.xml.dist└── .gitignore


Cada pacote em packages/ é uma biblioteca Composer independente com seu próprio composer.json. As aplicações em apps/ conectam esses pacotes como dependências locais. Essa estrutura permite:

  • Isolar a lógica e testar pacotes de forma independente
  • Usar tipagem estrita e autoloading PSR-4
  • Reutilizar código entre diferentes aplicações sem cópia


Configuração do Composer para trabalhar com monorepositório

O Composer é a principal ferramenta de gerenciamento de dependências em PHP. Para trabalhar com um monorepositório, usamos dois mecanismos-chave: caminhos locais (path) e manifesto raiz.



Passo 1: composer.json raiz

Na raiz do projeto, criamos um manifesto mínimo que define que este é um monorepositório:



{    "name": "mycompany/monorepo",    "type": "project",    "require": {        "php": "^8.1"    },    "autoload": {        "psr-4": {            "MyCompany\\\\": "packages/"        }    },    "scripts": {        "test": "phpunit",        "phpstan": "phpstan analyse"    }}


Passo 2: Dependências locais nos pacotes

Cada pacote em packages/users/ deve ter seu próprio composer.json. Por exemplo:



{    "name": "mycompany/users",    "type": "library",    "require": {        "php": "^8.1",        "mycompany/core": "*"    },    "autoload": {        "psr-4": {            "MyCompany\\\\Users\\\\": "src/"        }    }}

Blogs

Book Recommendations