Composer avançado
Esta aula aprofunda o uso do Composer, abordando scripts, versionamento semântico, dependências de desenvolvimento e criação de pacotes próprios. Você aprenderá a automatizar tarefas, gerenciar versões, separar dependências e publicar seus próprios pacotes.
O Composer é uma ferramenta essencial para o desenvolvimento PHP moderno, permitindo gerenciar dependências de forma eficiente. Nesta aula, exploraremos recursos avançados que vão além do básico, como scripts personalizados, versionamento semântico, dependências apenas para desenvolvimento e criação de pacotes próprios. Esses conceitos são fundamentais para projetos profissionais e colaborativos.
Dominar esses tópicos permitirá que você automatize tarefas repetitivas, mantenha compatibilidade entre versões, otimize o ambiente de desenvolvimento e compartilhe seu código de forma padronizada. Vamos mergulhar em cada um deles com exemplos práticos.
Scripts
O Composer permite definir scripts que são executados em eventos específicos do ciclo de vida do Composer, como após a instalação ou atualização de pacotes. Isso é útil para automatizar tarefas como limpeza de cache, geração de documentação ou migrações de banco de dados.
Os scripts são definidos na seção scripts do composer.json. Eles podem ser comandos do sistema, executáveis PHP ou até mesmo chamadas a outras ferramentas. Exemplo:
{
"scripts": {
"post-install-cmd": [
"@php -r 'echo \"Instalação concluída!\";'"
],
"post-update-cmd": [
"@composer dump-autoload"
],
"test": [
"phpunit"
]
}
}Para executar um script manualmente, use composer run-script test. Eventos comuns incluem pre-install-cmd, post-install-cmd, pre-update-cmd, post-update-cmd, pre-package-install, entre outros. Você também pode criar scripts personalizados sem vinculá-los a eventos.
Versionamento (semver)
O versionamento semântico (SemVer) é uma convenção amplamente adotada para gerenciar versões de pacotes. Ele segue o formato MAJOR.MINOR.PATCH: incrementos MAJOR indicam mudanças incompatíveis com versões anteriores, MINOR adicionam funcionalidades de forma compatível, e PATCH corrigem bugs de forma compatível.
No Composer, você especifica restrições de versão no require usando operadores como ^, ~, >=, etc. Por exemplo, ^1.2.3 permite qualquer versão de 1.2.3 até 2.0.0 (exclusive), enquanto ~1.2.3 permite de 1.2.3 até 1.3.0 (exclusive). É importante entender essas regras para evitar quebra de compatibilidade. O Composer respeita o SemVer ao resolver dependências, priorizando a estabilidade.
require-dev
A seção require-dev do composer.json lista dependências necessárias apenas para desenvolvimento, como ferramentas de teste, depuração ou documentação. Essas dependências não são instaladas em produção se você usar a flag --no-dev no comando composer install.
Exemplo de composer.json com require-dev:
{
"require": {
"monolog/monolog": "^2.0"
},
"require-dev": {
"phpunit/phpunit": "^9.5",
"mockery/mockery": "^1.4"
}
}Isso mantém o ambiente de produção leve e seguro. Lembre-se de sempre usar composer install --no-dev ao implantar em produção. Além disso, você pode definir scripts específicos para desenvolvimento, como executar testes automaticamente.
Pacotes próprios
Criar seus próprios pacotes e disponibilizá-los via Composer é uma prática que promove reuso e organização. Para isso, você precisa estruturar seu projeto como um pacote, com um composer.json adequado, e publicá-lo no Packagist (repositório público) ou em um repositório privado.
O composer.json de um pacote deve conter pelo menos os campos name (formato vendor/package), description, type (geralmente "library") e autoload (PSR-4 ou PSR-0). Exemplo:
{
"name": "meu-vendor/meu-pacote",
"description": "Um pacote exemplo",
"type": "library",
"autoload": {
"psr-4": {
"MeuVendor\\MeuPacote\\": "src/"
}
},
"require": {
"php": ">=7.4"
}
}Após criar o repositório no GitHub, você pode configurar o Packagist para sincronizar automaticamente. Para usar o pacote em outro projeto, basta adicionar "meu-vendor/meu-pacote": "^1.0" no require. Para pacotes privados, você pode usar o Satis ou Toran Proxy, ou referenciar diretamente o repositório VCS no composer.json do projeto consumidor.
Boas práticas
Sempre defina scripts para tarefas repetitivas, como testes e deploy. Use versionamento semântico para comunicar mudanças claramente. Separe dependências de desenvolvimento com require-dev para otimizar produção. Ao criar pacotes, siga PSR-4 para autoloading e documente bem o uso. Considere usar ferramentas como PHPStan ou Psalm para qualidade de código.
Referências
- Documentação oficial do Composer - Scripts
- Semantic Versioning 2.0.0
- Documentação oficial do Composer - require-dev
- Documentação oficial do Composer - Repositórios
- Packagist - Repositório de pacotes PHP
- PSR-4: Autoloading Standard
- Documentação oficial do Composer - Libraries
Exercícios
- Crie um script no Composer que execute o comando
php -l(lint) em todos os arquivos PHP do diretóriosrc/após a instalação. Escreva o trecho docomposer.jsoncorrespondente.✓ Resposta:{ "scripts": { "post-install-cmd": [ "find src/ -name '*.php' -exec php -l {} \\;" ] } } - Explique a diferença entre as restrições de versão
^1.2.3e~1.2.3no Composer. Dê um exemplo de qual versão seria permitida por cada uma a partir da versão 1.2.3.✓ Resposta:^1.2.3permite qualquer versão de 1.2.3 até 2.0.0 (exclusive), ou seja, versões 1.x.x. Já~1.2.3permite de 1.2.3 até 1.3.0 (exclusive), apenas versões 1.2.x. Exemplo:^1.2.3permite 1.9.9, mas~1.2.3não. - Adicione uma dependência de desenvolvimento (
require-dev) para o pacotephpunit/phpunitna versão ^9.5 nocomposer.jsonabaixo. Reescreva o JSON completo.{ "require": { "monolog/monolog": "^2.0" } }✓ Resposta:{ "require": { "monolog/monolog": "^2.0" }, "require-dev": { "phpunit/phpunit": "^9.5" } } - Crie um
composer.jsonmínimo para um pacote próprio chamadojoao/utilsque segue PSR-4 com namespaceJoao\Utilsapontando para a pastasrc. Inclua o requisito de PHP >= 8.0.✓ Resposta:{ "name": "joao/utils", "description": "Pacote de utilitários do João", "type": "library", "autoload": { "psr-4": { "Joao\\Utils\\": "src/" } }, "require": { "php": ">=8.0" } } - Qual comando do Composer você usaria para instalar apenas as dependências de produção (ignorando
require-dev)? Escreva o comando completo.✓ Resposta:composer install --no-dev