Статьи

Советы Composer для авторов и пользователей пакетов PHP

Composer , вероятно, является одним из наиболее важных инструментов для экосистемы PHP. Это стало стандартом де-факто для управления пакетами в PHP. Тем не менее, Composer имеет некоторые скрытые или не очень очевидные особенности, функциональность которых многие разработчики не знают. Независимо от того, являетесь ли вы автором пакета и maintaner или используете какой-то пакет в своем собственном проекте, при использовании Composer есть некоторые стандарты и рекомендации, с которыми вы должны быть знакомы и которым должны следовать. Эта статья предоставляет некоторые полезные советы в этом отношении.

Авторы пакета

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

Релизы тегов

Пожалуйста, отметьте релизы вашего пакета! А при пометке делайте это семантически . Не заставляйте других разработчиков зависеть от dev-master, который нестабилен с точки зрения флагов стабильности Composer, но также и в том смысле, что он может измениться в любое время.

Вы можете пометить релизы вручную, создав / нажав VCS теги, или, если ваш проект размещен на GitHub , вы можете создать релиз на странице вашего проекта.

Автозагрузка

Composer имеет собственный механизм автозагрузки , и помимо спецификации автозагрузки для ваших источников, вы можете определить ее в случае классов из пространства имен ваших тестов (вы пишете модульные тесты для своей библиотеки, верно?). Многим разработчикам все равно, и они устанавливают автозагрузку composer.jsonтаким образом:

{
    "autoload": {
        "psr-4": { 
            "MyLibrary\\": "src/",
            "MyLibrary\\Tests\\": "tests/"
        }
    }
}

Но это плохо. НЕ загрязняйте автозагрузчик при производстве, когда ваш пакет используется как зависимость. Composer также имеет autoload-devсвойство для целей разработки, и вот правильная спецификация автозагрузки для этого примера:

{
    "autoload": {
        "psr-4": { "MyLibrary\\": "src/" }
    },
    "autoload-dev": {
        "psr-4": { "MyLibrary\\Tests\\": "tests/" }
    }
}

При желании вы можете оптимизировать автозагрузку исходных файлов вашей библиотеки, указав classmapправила:

{
    "autoload": {
        "psr-4": { "MyLibrary\\": "src/" },
        "classmap": ["src/"]
    }
}

Филиал Псевдоним

Ветка псевдоним этого свойство , которое может быть введено в composer.json, с целью отображения не-версии , как имена филиалов (то есть мастер, разработка) в сопоставимые имена версии (то есть 1.0, 2.1.0). Это полезно в тех случаях, когда кто-то хочет потребовать последнюю версию dev-master, и может возникнуть проблема, если этого требуют другие пакеты 1.0.*, что приведет к конфликту, поскольку dev-masterне соответствует 1.0.*ограничению. Псевдонимы могут быть определены в extraразделе composer.json, например:

{
    "extra": {
        "branch-alias": {
            "dev-master": "1.0.x-dev"
        }
    }
}

В документации Composer есть отличная статья о псевдонимах .

Псевдонимы веток не так важны, поскольку пользователи пакетов все еще могут обойти это препятствие, требуя встроенные псевдонимы .

Пакетные пользователи

Мы, разработчики PHP, пользуемся преимуществами наличия множества полезных библиотек, которые могут быть легко интегрированы в наш проект с помощью Composer. И все же стоит обратить внимание на некоторые важные детали.

Точные требования к версии

Устанавливая требования к версии ваших зависимостей, вы хотите быть максимально точными. Объявление ограничения версии *следует избегать любой ценой . Кроме того, в зависимости от последней версии разработки, другими словами, использование dev-masterограничений, на мой взгляд, небрежно и рискованно, и такого подхода следует избегать, даже если пакет не имеет выпусков, что является недостатком, за который отвечает его сопровождающий.

По крайней мере , вы должны указать ограничения в виде шаблонов с *символом, например: 1.0.*, 2.*и подобные. Но кроме подстановочного оператора, Composer предлагает так называемые операторы «следующего значительного выпуска» — тильды и каретки , которые в основном полезны для проектов, уважающих семантическое управление версиями, и рекомендуются для максимальной совместимости между пакетами.

Тем не менее, всегда существует риск того, что какая-то ошибка или разрыв BC будут в конечном итоге возникать в некоторых ваших зависимостях, которые нарушат ваш код. Конечно, вы можете быть строгими и указывать точную версию пакета, но, как следствие, этот подход может привести к ситуации, когда разрешение зависимостей в конечном итоге завершится ошибкой и прервет любые процедуры установки или обновления, если для какой-либо другой зависимости требуется другая версия.

composer.lock

Цель файла блокировки — записать точные версии зависимостей в вашем проекте. Это означает, что после установки зависимостей и фиксации composer.lockфайла, когда ваш коллега запускается composer install, он / она получит те же версии зависимостей, даже если за это время были выпущены более новые версии.

Вопрос, который часто возникает в отношении composer.lockфайла, заключается в том, следует ли его вообще хранить в репо. Это вечные споры, да? Но в моем случае дилеммы нет, я следую этим простым правилам:

  • Всегда совершайте composer.lock в случае приложений
  • Никогда не передайте composer.lock в случае компонентов

Другими словами, это означает, что вы должны фиксировать composer.lockфайл только для приложений, но вы никогда не должны фиксировать его в случае библиотеки, которую кто-то еще устанавливает и использует в своем проекте.

Причины в случае применения очевидны. Установка composer.lockв версию гарантирует, что вы и ваши товарищи по команде используете точно такие же версии ваших пакетов зависимостей. Что еще более важно, это гарантирует, что одни и те же зависимости используются как в рабочей среде, так и в среде разработки. Это также означает, что нет необходимости искать версии или разрешать зависимости, что ускоряет само развертывание.

Что касается причин отказа composer.lockот фиксации в случае разработки компонентов, если вы заблокируете зависимости для определенной версии, вы, возможно, не поймете, что ваша библиотека не работает с какой-то более новой версией, даже если ваша сборка CI проходит, потому что она всегда будет работать с одной и той же версией зависимости.

Развертывание производства

Хорошо, теперь нет никаких сомнений в том, что composer.lockоно зафиксировано, поэтому развертывание должно быть довольно простым, вам нужно всего лишь запустить composer installкоманду, которая будет читать заблокированные версии зависимостей и устанавливать их, верно? Не совсем.

В производственной среде вы хотите убедиться, что все средства разработки исключены. Вы делаете это, используя –no-devфлаг:

composer install –no-dev

Это полностью исключит установку всех пакетов, необходимых для разработки ( require-devпакетов), но также при генерации автозагрузчика Composer будут пропущены правила autoload-dev .

Еще один флаг, который очень желателен в производстве --optimize-autoloader. Он сгенерирует карту классов на основе обычных правил автозагрузки (PSR-0/4), что ускорит автозагрузку в вашем приложении.

Имея это в виду, вот рекомендуемый способ установки composer при выполнении производственного развертывания:

composer install --no-ansi --no-dev --no-interaction --no-progress --optimize-autoloader

TL; DR

Советы авторам пакетов:

  • Помечайте релизы вашего пакета и делайте это семантически .
  • Не загрязняйте автозагрузчик Composer при производстве пространством имен модульных тестов; использовать autoload-dev.
  • Используйте псевдонимы веток .

Советы для пользователей пакета:

  • Будьте максимально точны при определении требований к версии; Используйте следующие важные выпуски операторов .
  • Всегда совершайте composer.lock в случае приложений, никогда в случае компонентов
  • Команда рабочего развертывания установки: composer install --no-ansi --no-dev --no-interaction --no-progress --optimize-autoloader

Ссылки