Все любят кричать "пиши переиспользуемый код". Только потом этот "код" превращается в копипасту из проекта в проект. Решение старое как говно мамонта — вынеси в пакет. Laravel это умеет. Но тут есть нюансы.
Сколько раз было: сидишь такой, пилишь проект на Laravel, и вдруг понимаешь, что уже четвёртый раз пишешь один и тот же хелпер для работы с каким-нибудь API или свою логику уведомлений. И вроде руки чешутся "переиспользовать", но по факту ты просто тащишь файлы по папкам как бродячий цирк.
А потом начинается ад: где-то у тебя Utils.php, где-то HelperTrait.php, и хрен вспомнишь, в какой версии проекта лежит последний "правильный" вариант. Вот для этого и существуют пакеты. Не потому что "правильно и модульно", а потому что задолбало копипастить.
Laravel здесь не изобретает велосипед — просто подсовывает тебе удобный способ втащить свой код как полноценную библиотеку.
Скелет пакета
Старт банален:
mkdir my-package
cd my-package
Внутри пилим composer.json. Да-да, без него это даже не пакет, а просто папка.
{
"name": "your-vendor/my-package",
"description": "Just another package",
"type": "library",
"require": {
"php": "^7.3 || ^8.0",
"illuminate/support": "^8.0"
},
"autoload": {
"psr-4": {
"YourVendor\\MyPackage\\": "src/"
}
},
"extra": {
"laravel": {
"providers": [
"YourVendor\\MyPackage\\MyPackageServiceProvider"
]
}
} } Вот тут важный момент: autoload и providers. Если их забудешь — Laravel даже не узнает о твоём чуде.
Сам пакет
Создаём src/ и туда кидаем свой "мозг":
<?php
namespace YourVendor\MyPackage;
class MyPackage
{
public function doSomething()
{
// твой код, который ты устал копипастить
}
}
Вот и весь "фреймворк". Пакет — это просто папка с классами.
ServiceProvider: без него ты никто
Laravel грузит всё через ServiceProvider. Не будет его — твой пакет так и останется мёртвым архивом.
<?php
namespace YourVendor\MyPackage;
use Illuminate\Support\ServiceProvider;
class MyPackageServiceProvider extends ServiceProvider
{
public function boot()
{
// маршруты, вьюхи, переводы
}
public function register()
{
// бинды в контейнер, синглтоны, сервисы
}
}
В boot() ты можешь подсунуть Laravel свои маршруты, вьюхи или конфиги. В register() — повесить зависимости.
Подключаем в проект
В корне Laravel-проекта:
composer require your-vendor/my-package
И вуаля — пакет встал, Laravel его видит.
Теперь можно использовать:
use YourVendor\MyPackage\MyPackage;
$myPackage = new MyPackage();
$myPackage->doSomething();
Публикация ресурсов
Если у тебя там лежат свои config, views, lang — Laravel даёт команду:
php artisan vendor:publish --provider="YourVendor\MyPackage\MyPackageServiceProvider" После этого твой конфиг или шаблон уедет в проект. И юзер сможет ковырять его без страха, что при обновлении пакета всё перепишется.
Зачем это вообще?
— Чтобы не копипастить одни и те же классы в десяти проектах.
— Чтобы не искать, "а в какой версии у нас был фикс бага с JWT?".
— Чтобы твой код можно было воткнуть командой composer require, а не ручным слиянием файлов.
Это всё.
Тёмная сторона
Тут без сказок:
- Если ты любишь менять API пакета каждые два дня — ненавидеть тебя будут даже твои коллеги.
- Если твой пакет жёстко завязан на конкретную версию Laravel — рано или поздно ты упрёшься лбом в апгрейд.
- Если пакет настолько "уникален", что нужен только тебе — может, он вообще не нужен как пакет?
Итог
Создание пакетов в Laravel — это не про "модульность ради модульности". Это про лень и здравый смысл. Устал тащить одни и те же костыли из проекта в проект? Запихни их в пакет. Не устал — забей, катайся дальше на копипасте.
0 комментариев