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