В чем разница между require и require-dev в composer.json?

Ответ

Секции require и require-dev в файле composer.json разделяют зависимости по их назначению в жизненном цикле проекта.

require содержит пакеты, необходимые для работы приложения в любом окружении, включая продакшен. Это основные зависимости.

require-dev содержит пакеты, нужные только во время разработки, тестирования или CI/CD. Они не требуются для работы приложения на боевом сервере.

Практический пример composer.json:

{
    "name": "myapp/project",
    "require": {
        "laravel/framework": "^10.0",
        "guzzlehttp/guzzle": "^7.0"
    },
    "require-dev": {
        "phpunit/phpunit": "^10.0",
        "fakerphp/faker": "^1.20",
        "barryvdh/laravel-debugbar": "^3.0"
    }
}

Как это работает при установке:

  • composer install — по умолчанию устанавливает пакеты из обеих секций.
  • composer install --no-dev — устанавливает только пакеты из require. Это стандартная команда для деплоя на продакшен.
  • composer update — обновляет пакеты согласно правилам версионирования в composer.json. Флаг --no-dev также игнорирует dev-зависимости.

Типичное разделение:

  • В require: фреймворки (Laravel, Symfony), библиотеки для работы с БД (Doctrine), HTTP-клиенты, кеширование и т.д.
  • В require-dev: фреймворки для тестирования (PHPUnit, Pest), генераторы тестовых данных (Faker), инструменты для профилирования и отладки (Xdebug, Laravel Debugbar), статические анализаторы (PHPStan, Psalm).

Важно: При развёртывании приложения всегда используйте composer install --no-dev --optimize-autoloader, чтобы избежать установки ненужных в продакшене пакетов и ускорить автозагрузку.

Ответ 18+ 🔞

Ёпта, слушай сюда, разберём эту тему, чтобы у тебя в голове всё встало на свои места, как бутылки после хорошей панёровки. Есть у нас в composer.json две главные банды: require и require-dev. И они там не просто так сидят, у них задачи разные, как у рабочего и у прораба на стройке.

require — это наш основной состав, без них проект просто накроется медным тазом. Это те пакеты, без которых твоё приложение — просто пустая папка. Laravel, Symfony, Guzzle — всё, что нужно для работы и на локалке, и на продакшене. Без них — пизда рулю.

require-dev — это наша обслуга, наш инструментарий для разработки. Сюда пихаем всё, что нужно, пока ты кодишь и тестируешь, но на боевом сервере этому делать ни хуя. PHPUnit для тестов, Faker чтобы нагенерить тестовых данных, всякие дебаг-бары, которые в продакшене только дыру в безопасности откроют. Поставил это на продакшен — сам от себя охуел.

Вот смотри, как это выглядит в живую:

{
    "name": "myapp/project",
    "require": {
        "laravel/framework": "^10.0",
        "guzzlehttp/guzzle": "^7.0"
    },
    "require-dev": {
        "phpunit/phpunit": "^10.0",
        "fakerphp/faker": "^1.20",
        "barryvdh/laravel-debugbar": "^3.0"
    }
}

Видишь? Фреймворк и HTTP-клиент — в основном отряде. Всё остальное — инструменты для внутренних разборок.

Как этим хозяйством управлять:

  • composer install — ставит всё подряд, и рабочих, и обслугу. Для локалки — то, что надо.
  • composer install --no-dev — вот это уже умный ход. Ставит только бойцов из require. Эту команду и надо запускать, когда заливаешь всё на продакшен-сервер, чтобы там не болтался лишний хлам.
  • composer update — всех апдейтит. И тоже, если добавишь --no-dev, то dev-зависимости останутся в покое.

Чтобы совсем понятно было, кто куда идёт:

  • В require: Фреймворки, библиотеки для БД, кеширования, отправки писем — короче, всё, что делает продукт продуктом.
  • В require-dev: Всё для разработки: тестеры (PHPUnit), генераторы фейковых данных (Faker), отладчики (Debugbar, Xdebug), линтеры (PHPStan). На продакшене этому месту в пизду.

Главный вывод, который ты должен высечь у себя в подкорке: Когда собираешь проект для прода, всегда, блядь, всегда делай composer install --no-dev --optimize-autoloader. Это уберёт весь dev-мусор и ещё автозагрузку оптимизирует. Не сделаешь — получишь овердохуища лишних файлов и, возможно, дыр в безопасности. Не будь распиздяем, делай правильно.