Drupal 8: Работа с Composer

03.09.2016

В общем дело тут такое, вообще эту статью я не планировал и вообще даже не знал об этом. Хотел написать про одно, полез в другое, а оказалось вот это :) Поэтому могут быть неточности, так как с композером раньше серьезно сталкиваться не приходилось.

Суть в том, что в Drupal 8.1 в ядро интегрировали composer и теперь всё можно делать через него. Это на самом деле очень удобно, так как зависимости проекта хранятся в файле, их очень легко установить в одну команду и обновить. Но не без недостатков, на данный момент, по крайней мере у меня, drush и drupal compose не умеют с этим обращаться, и если у модуля какая-то зависимость через композер, то он её не установит, и придется контролировать руками, также установка через обе тулзы не добавляют модули в зависимости композера и теряется функционал композера и часть его смысла. Не ясно как узнавать доступные версии для пакета на установку, только указав неверную версию он выдает какой-то список, может кто в комментах подскажет.

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

Установка ядра через composer

Если у вас чистый проект, то проще ядро сразу тянуть через композер, делается это очень просто

# Загрузка текущей стабильной версии Drupal 8.1
composer create-project drupal/drupal FOLDER 8.1.*@stable
# В предыдущем примере ядро скачается в папку FOLDER,
# но если вы хотите чтобы ядро развернулось в текущей папке
# используйте данную команду
composer create-project drupal/drupal . 8.1.*@stable
# Хотите использовать dev версию ядра?
composer create-project drupal/drupal . 8.1.*@dev

Подключение репозиториев

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

Для полноценной работы нужно подключить репозитории Drupal.org, так как по умолчанию они не подключены, вы не сможете устанавливать проекты с drupal.org, так как композер их просто не найдет. Все по принципу репозиториев в Linux, если вы, конечно, знакомы с этим подходом.

Добавление Drupal.org репозитория в Composer
composer config repositories.drupal composer https://packages.drupal.org/8

То же самое и работает для Drupal 7 https://packages.drupal.org/7, но там composer.json придется заготовить руками как я понял, не тестил, но поддерживается.

Если вы всё сделали правильно, в корневом composer.json должно появиться упоминание подключенного нами репозитория.

Подключенный репозиторий для Drupal 8

Установка модулей и тем через Composer

После подключения репозитория, нам станут доступны для загрузки все модули и темы с drupal.org. Для загрузки модулей и тем используется команда в следующем формате: composer require drupal/<project_name>, где вы и подставляете название проекта.

Примеры установок через композер
composer require drupal/token
composer require drupal/rules
Модули в зависимостях composer.json
Модули в своей папке.

Как вы видите, модули скачались, добавились в зависимости композера, а также разместились в папке modules. Теперь их нужно включить через drush, drupal console или административный интерфейс, это уже не играет никакой роли.

Установка в modules/contrib

Как вы можете заметить, у меня есть папка contrib, куда я складываю модули с drupal.org, и если drush и drupal console это учитывали и складывали модули туда, то composer об этом не знает.

Для этого нам нужен плагин для composer, который позволит указывать папку назначения. Это плагин composer custom installer. Возможно есть ещё какие-то решения, но на drupal.org в комментариях рекомендуют использовать именно его.

Первым делом нам нужно установить его.

composer require davidbarratt/custom-installer

После того как установили этот плагин, мы должны в package.json написать для него настройки. Для этого, в раздел "extra" мы добавим ему свои настройки. Учтите что там уже есть настройки, поэтому не нужно затирать, а лишь добавлять.

"extra": {
    "custom-installer": {
        "modules/contrib/{$name}/":["type:drupal-module"]
    }
}

Теперь вы можете попробовать установить новый модуль, или написать composer install и вы заметите, что старые модули ещё раз скачались, только в этот раз в contrib. Поэтому лучше сразу всё это в начале проекта проконтролировать, либо затем удалить их из корневой папки modules и сбросишь кэш.

Новая структура загрузки.

Если вы обратили внимание на консоль, когда устанавливали модули или же взглянули в зависимости composer.json, то могли бы заметить, что все модули устанавливаются по умолчанию в dev версии. Это не очень хорошо. Для того чтобы качались стабильные версии, вы должны указать соответствующую версию в формате composer require drupal/<project_name>:<version>

Примеры установки конкретных версий
# Последняя стабильная версия на данный момент.
composer require drupal/token:1.0-beta-1
# Установка dev версии
composer require drupal/token:1.x-dev
# Скачать последнюю стабильную версию 1.x
# На момент написания, последняя 1.0-beta-1, её он и скачает.
composer require drupal/token:1.*
# Самым надежным и правильным будет следующий вариант.
# Он скачает последнюю стабильную версию 1.x
# Но если уже выйдет 2.x версию у модуля, он её не скачает.
# ~1.0 равносильно >=1.0 <2.0.0
# ~1.0.0 равносильно >=1.0.0 <1.1.0
composer require drupal/token:~1.0-stable

Больше всего о версиях, как их указывать и как они себя ведут на официальном сайте composer.

Удаление пакетов

Всё очень просто, выполняется это одной командой и это удаляет как прописанную зависимость, так и физически модуль. Но будьте крайне осторожны, ведь сначала надо удалить модуль из друпала, а уже затем физически.

composer remove drupal/token

Поиск пакетов

Вы также можете искать модули через композер. Всё очень просто.

composer search token

Автоматическое применение патчей

Бывает что в модуле есть какая-то ошибка, которая пофикшена только в dev, но вы хотите остаться на стабильной версии, или вообще пофикшена, но нету решения нигде как в патче. Раньше патчи надо было применять руками, теперь это можно скинуть на композер.

Композер, сам по себе, не умеет это делать, но есть плагин который это умеет делать.

Установка composer patches
composer require cweagans/composer-patches
"extra": {
    "patches": {
        "drupal/drupal": {
            "Add startup configuration for PHP server": "https://www.drupal.org/files/issues/add_a_startup-1543858-30.patch"
        }
    }
}

Как видно из примера выше, для патчей мы должны создать раздел patches в разделе extra. Далее указывается пакет, к которому применяется патч, описание и путь до патча.

Использование composer.json в своём модуле

В можете объявить свой composer.json в кастомном или контрибном модуле, не важно, есть у модуля зависимости или нет. В обычном виде он выглядит следующим образом.

composer.json без зависимостей
{
    "name": "drupal/example",
    "description": "This is an example composer.json for example module.",
    "type": "drupal-module",
    "license": "GPL-2.0+"
}

Как видите, вы можете указать лишь описание, название, тип и лицензию. Я так понимаю, что для кастомных модулей указывать drupal/example некорректно, так как могут возникнуть проблемы если появится соответствующий модуль в репозитории. Как мне кажется, правильнее указывать в формате name/module_name. Где в начале вы можете указать свой ник, имя, компанию. Если у кого есть опыт с этим, поправьте меня в комментариях.

К слову, указание типа обязательно. На данный момент существуют следующие типы:

  • drupal-module
  • drupal-theme
  • drupal-library
  • drupal-profile
  • drupal-drush

А ниже более комплексный пример, взято из модуля Mobile Detect.

{
  "name": "drupal/mobile_detect",
  "description": "Mobile_Detect is a lightweight PHP class for detecting mobile devices.",
  "type": "drupal-module",
  "homepage": "https://drupal.org/project/mobile_detect",
  "authors": [
    {
      "name": "Matthew Donadio (mpdonadio)",
      "homepage": "https://www.drupal.org/u/mpdonadio",
      "role": "Maintainer"
    },
    {
      "name": "Darryl Norris (darol100)",
      "email": "admin@darrylnorris.com",
      "homepage": "https://www.drupal.org/u/darol100",
      "role": "Co-maintainer"
    }
  ],
  "support": {
    "issues": "https://drupal.org/project/issues/mobile_detect",
    "irc": "irc://irc.freenode.org/drupal-contribute",
    "source": "https://cgit.drupalcode.org/mobile_detect"
  },
  "license": "GPL-2.0+",
  "minimum-stability": "dev",
  "require": {
    "mobiledetect/mobiledetectlib": "~2.8"
  }
}

Для чего это? Ну по сути, если нет никаких зависимостей, ни для чего. Если же есть зависимости, то когда ваш модуль установят через composer, он также установит и все его зависимости.

В заключении

Как я уже написал, у меня крайне мало знаний о composer, я это всё раскопал, лишь потому что для другого гайда потребовался модуль, в котором как раз лежит composer.json со своими зависимостями, без которых он не заводится. Ну я решил и разобраться что к чему. Если есть замечания или предложения дополнить\поправить что-то, прошу в комментарии.

Также стоить указать что данный подход не обязателен, но если вы нарветесь на модуль с зависимостями через композер, вы как минимум его должны будете закачать через композер. Устанавливать все модули через него, или же только с composer.json где прописаны зависимости - на ваше усмотрение. На drupal.org нету никаких конретик по этому поводу. На данный момент это предоставляется как вариант организации проекта, репозитории находятся в бета режиме и некоторые возможности composer ещё не поддерживаются. Например, семантические версии. Но это официальная возможность начиная с 8.1 и для всех последующих версий. Соответственно из-за этого модуль Composer Manager для Drupal 8 deprecated.

Комментарии

xandeadx
03.09.2016

Композер нужен только если пишешь/ставишь модуль использующий либы с packagist.org. Для другого пока бесполезен, drush + drush make более функциональны.

Niklan
03.09.2016

Так и есть, вот официальное сравнение Drush vs Composer. Но я так понял композер так тесно интегрируют именно для того чтобы заменить им drush make.

mumac
24.12.2016

Добрый день, спасибо за труд и статью. Может уже что-то поменялось, но у меня модули начали устанавливаться в определенную папку, после изменения записи в "extra" на "installer-paths": { "modules/contrib/{$name}/":["type:drupal-module"] }

Алексей
06.03.2017

drush и drupal compose не умеют с этим обращаться

Drush и drupal consle? Опечатка?

Алексей
06.03.2017

drush и drupal compose не умеют с этим обращаться

Drush и drupal consle? Опечатка?

Содержимое данного поля является приватным и не предназначено для показа.