С пакетами и библиотеками жизнь разработчика упрощается. Пакет — это часть кода многократного использования, добавляемая в любое приложение и применяемая без каких-либо изменений для расширения функционала этого кода.
Создадим и опубликуем пакет composer на PHP.
Что понадобится
- Composer.
- Код пакета проекта.
- Учетная запись на Github и в Packagist.
Что такое composer?
- Это диспетчер зависимостей для пакетов или библиотек PHP.
- Создан по примеру npm (Node.js) и bundler (Ruby).
- Работает с пакетами официального репозитория packagist.org: так известно местонахождение кода пакета — обычно это публичный репозиторий на Github.
Готовим пакет
Вот структура проекта:
sfmok ~/my-package> tree
.
├── src
│ └── HelloWorld.php
└── tests
└── HelloWorldTest.php
Сделаем ее в виде пакета: поделиться им можно точно так же, каким бы ни был пакет и/или его размер.
Начнем с генерирования в composer конфигурационного файла composer.json
, переходим к пути пакета проекта в терминале и запускаем:
composer init
Здесь нужно внимательно рассмотреть вопросы:
- Проверяем соответствие пакета способу именования
<vendor>
/<name>
, где:
<vendor>
— это имя автора, и оно должно быть уникальным, например имя пользователя на Github sfmok;<name>
— это название самого пакета, например hello-world.
2. Тип пакета:
- library: по умолчанию. Файлы им скопируются в
vendor
. - project: так обозначается проект, а не библиотека. Например, оболочки приложений, такие как стандартная версия Symfony; системы управления содержимым, такие как установщик SilverStripe; полноценные приложения, распространяемые в виде пакетов. Это применяется в интегрированных средах разработки, где предоставляются листинги проектов для инициализации при создании новой рабочей области.
- metapackage: пустой пакет с требованиями, которым запускается их установка; но файлов в нем нет, и в файловую систему ничего не записывается. Поэтому для его установки ключ
dist
илиsource
не требуется. - composer-plugin: в таком пакете может быть установщик других пакетов пользовательского типа. Подробнее здесь.
- symfony-bundle: применяется в бандлах фреймворков Symfony для автоматического — с помощью Flex — включения бандла при его установке.
3. Зависимости require
и require-dev
: в composer сообщается, от каких пакетов зависит проект, например php для всех сред, а phpunit для среды разработки.
4. Сопоставление при автозагрузке PSR-4: пространство имен пакета сопоставляется с корневым пакетом src
. По умолчанию совпадает с названием пакета.
После подтверждения генерирования в пакет проекта добавлен файл composer.json:
sfmok ~/my-package> tree
.
├── composer.json
├── src
│ └── HelloWord.php
└── tests
└── HelloWordTest.php
Командой composer init
не поддерживаются следующие параметры конфигурации.
Они добавляются в файл composer.json
вручную. Например, добавим в пакет пространство имен PSR-4 autoload-dev:
{
"name": "sfmok/hello-world",
"description": "A hello world example package.",
"type": "library",
"require": {
"php": "^8.0"
},
"require-dev": {
"phpunit/phpunit": "^9.0"
},
"license": "MIT",
"autoload": {
"psr-4": {
"Sfmok\\HelloWorld\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Sfmok\\HelloWorld\\Tests\\": "tests/"
}
},
"authors": [
{
"name": "Mokhtar Tlili",
"email": "[email protected]"
}
]
}
Тесты должны быть зелеными. Дальше добавляем:
- файл
README
с описанием пакета и особенностей его использования; - файл
.gitignore
, чтобы исключить отслеживание лишних файлов и каталогов, например папкуvendor
для пакетов зависимостей, папкуIDE
(часто скрытую) и т. д.; - файл
.gitattributes
(необязательно) для игнорирования экспорта конкретных файлов и каталогов, когда в composer архивируется пакет; его содержимое — относительные пути с последующим атрибутом, например/tests export-ignore
.
Публикуем
Пакет публикуется официально в два этапа.
- Размещается в публичном репозитории, например на Github.
- Регистрируется в Packagist.
Размещаем на Github
Создаем новый репозиторий hello-world: название то же, что у пакета.
Версионируем пакет, инициализируя локальный репозиторий, затем отслеживаем и фиксируем изменения во всем проекте:
sfmok ~/my-package> git init --initial-branch=main
Initialized empty Git repository in /Users/sfmok/projects/my-package/.git/
sfmok ~/my-package (main)> git add .
sfmok ~/my-package (main)> git commit -m "first commit"
[main (root-commit) 25b914a] first commit
6 files changed, 68 insertions(+)
create mode 100644 .gitattributes
create mode 100644 .gitignore
create mode 100644 README.md
create mode 100644 composer.json
create mode 100644 src/HelloWorld.php
create mode 100644 tests/HelloWorldTest.php
Публикуем пакет, добавляя главную ветку в публичный репозиторий на Github:
sfmok ~/my-package (main)> git remote add origin https://github.com/sfmok/hello-world.git
sfmok ~/my-package (main)> git push -u origin main
Enumerating objects: 10, done.
Counting objects: 100% (10/10), done.
Delta compression using up to 8 threads
Compressing objects: 100% (7/7), done.
Writing objects: 100% (10/10), 1.29 KiB | 661.00 KiB/s, done.
Total 10 (delta 0), reused 0 (delta 0), pack-reused 0
To https://github.com/sfmok/hello-world.git
* [new branch] main -> main
Branch 'main' set up to track remote branch 'main' from 'origin'.
Репозиторий выглядит так:
Чтобы сделать версию v1.0.0 первого релиза, нажимаем на Releases и создаем для него тег:
Заполняем форму релиза и публикуем:
Регистрируем в Packagist
Входим через учетную запись Github и отправляем пакет:
Нажимаем кнопку check — проверится уникальность названия пакета.
В случае успеха появится кнопка отправки:
Отправленный пакет несколько минут обрабатывается, затем публикуется:
Теперь пакет официально опубликован и готов к использованию в любом проекте на PHP, например в composer require sfmok/hello-world
:
В composer обнаружен первый релиз v1.0.0:
<?php
// src/Test.php
require_once __DIR__ . '/../vendor/autoload.php';
use Sfmok\HelloWorld\HelloWorld;
$greeting = new HelloWorld();
echo $greeting->hello();
Читайте также:
Читайте нас в Telegram, VK и Дзен
Перевод статьи Mokhtar Tlili: Create and publish a PHP composer package