Монорепозиторий с PHP: организация кода и лучшие практики

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Монорепозиторий с PHP: организация кода и лучшие практики

В современной PHP-разработке всё чаще встаёт вопрос об эффективной организации кода. Традиционный подход с множеством отдельных репозиториев (мультирепозиторий) имеет свои недостатки: сложность синхронизации версий, дублирование конфигураций и проблемы с рефакторингом. Альтернативой выступает монорепозиторий (monorepo) — стратегия, при которой все связанные проекты, пакеты и библиотеки хранятся в едином репозитории. В этой статье мы разберём, как организовать монорепозиторий с PHP, какие инструменты использовать и какие подводные камни учесть.

Что такое монорепозиторий и зачем он нужен PHP-проектам?

Монорепозиторий — это единое хранилище кода, содержащее несколько проектов или пакетов. В мире PHP классический пример — Laravel, который включает в себя фреймворк, пакеты для аутентификации, очередей, почты и другие компоненты в одном репозитории.

Основные преимущества для PHP-проектов:

  • Упрощение рефакторинга — изменения в одном пакете сразу видны всем зависимым компонентам, не нужно публиковать и обновлять версии каждого пакета отдельно.
  • Целостность версий — все пакеты используют одну и ту же версию зависимостей, что исключает конфликты типов.
  • Единая CI/CD — один конвейер сборки для всех компонентов, упрощение тестирования кросс-пакетных изменений.
  • Улучшение совместной работы — разработчики видят весь код проекта, проще проводить code review и поддерживать единые стандарты кодирования.

Однако монорепозиторий подходит не всем. Если ваши проекты слабо связаны или имеют разные циклы релизов, мультирепозиторий может быть удобнее. Для средних и крупных PHP-проектов с тесной интеграцией компонентов монорепозиторий часто становится оптимальным выбором.

Структура монорепозитория на PHP

Правильная структура — основа успешного монорепозитория. Рассмотрим типовую организацию на примере проекта с ядром (core), несколькими модулями и тестами.

my-php-monorepo/
├── packages/
│   ├── core/
│   │   ├── src/
│   │   │   └── CoreService.php
│   │   ├── tests/
│   │   └── composer.json
│   ├── module-auth/
│   │   ├── src/
│   │   ├── tests/
│   │   └── composer.json
│   └── module-payment/
│       ├── src/
│       ├── tests/
│       └── composer.json
├── apps/
│   ├── api/
│   │   ├── public/
│   │   ├── src/
│   │   └── composer.json
│   └── console/
│       ├── src/
│       └── composer.json
├── tests/
│   └── IntegrationTest.php
├── composer.json (корневой)
├── phpunit.xml.dist
├── .gitignore
└── README.md

Ключевые принципы организации:

  • Разделение на пакеты (packages) — каждый пакет имеет свой composer.json с именем, автозагрузкой и зависимостями.
  • Приложения (apps) — точки входа (API, консольные команды), которые собирают пакеты вместе.
  • Корневой composer.json — содержит мета-конфигурацию для работы с монорепозиторием.

Настройка корневого composer.json

Для работы монорепозитория необходимо настроить корневой composer.json так, чтобы пакеты были доступны локально, без публикации в Packagist.

{
    "name": "my-company/my-monorepo",
    "type": "project",
    "require": {
        "php": "^8.1",
        "my-company/core": "*",
        "my-company/module-auth": "*",
        "my-company/module-payment": "*"
    },
    "autoload": {
        "psr-4": {
            "MyCompany\\": "packages/"
        }
    },
    "repositories": [
        {
            "type": "path",
            "url": "packages/*",
            "options": {
                "symlink": true
            }
        }
    ],
    "scripts": {
        "test": "phpunit",
        "cs-fix": "php-cs-fixer fix"
    }
}

Параметр "type": "path" указывает Composer, что пакеты находятся локально. Опция "symlink": true создаёт симлинки, что позволяет разработчику видеть изменения в реальном времени без переустановки зависимостей.

Инструменты для работы с монорепозиторием в PHP

Хотя базовую структуру можно настроить вручную, для полноценной работы с монорепозиторием в PHP рекомендуется использовать специализированные инструменты.

1. Monorepo Builder (symplify/monorepo-builder)

Это самый популярный инструмент для PHP. Он автоматизирует задачи, связанные с монорепозиторием: синхронизацию версий, релизы, разделение на отдельные репозитории (split) и многое другое.

Установка:

composer require symplify/monorepo-builder --dev

Пример конфигурации monorepo-builder.php:

use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use Symplify\MonorepoBuilder\ValueObject\Option;

return static function (ContainerConfigurator $containerConfigurator): void {
    $parameters = $containerConfigurator->parameters();
    
    // Указываем, где находятся пакеты
    $parameters->set(Option::PACKAGE_DIRECTORIES, [
        __DIR__ . '/packages',
    ]);
    
    // Пакеты, которые не нужно публиковать отдельно
    $parameters->set(Option::DATA_TO_REMOVE, [
        'require' => [
            'phpunit/phpunit' => '*',
        ],
    ]);
};

Основные команды:

  • vendor/bin/monorepo-builder merge — объединяет composer.json всех пакетов в корневой.
  • vendor/bin/monorepo-builder split — разделяет монорепозиторий на отдельные репозитории для публикации.
  • vendor/bin/monorepo-builder bump-interdependency — синхронизирует версии зависимостей между пак

Блоги

Рекомендаций по книгам