Зависимости модулей
Файл module.json является центральным конфигурационным файлом модуля. Он определяет метаданные, провайдеры и зависимости модуля.
Структура module.json
Базовый пример
{
"name": "Blog",
"version": "1.0.0",
"description": "Модуль блога для публикации статей",
"authors": ["Разработчик"],
"providers": [
"Flute\\Modules\\Blog\\Providers\\BlogProvider"
],
"dependencies": {
"php": ">=8.2",
"flute": ">=1.0.0"
}
}Полный пример со всеми зависимостями
{
"name": "Shop",
"version": "1.2.0",
"description": "Модуль интернет-магазина",
"authors": ["Команда разработки"],
"url": "https://github.com/example/shop",
"providers": [
"Flute\\Modules\\Shop\\Providers\\ShopProvider",
"Flute\\Modules\\Shop\\Providers\\ShopAdminProvider"
],
"dependencies": {
"php": ">=8.2",
"flute": ">=1.0.0",
"modules": {
"Payments": ">=1.0.0",
"Notifications": ">=1.0.0"
},
"extensions": ["gd", "mbstring", "curl"],
"composer": {
"intervention/image": "^2.7",
"guzzlehttp/guzzle": "^7.0"
},
"theme": {
"standard": ">=1.0.0"
}
}
}Параметры конфигурации
| Параметр | Тип | Обязательный | Описание |
|---|---|---|---|
name | string | ✅ | Уникальное название модуля |
version | string | ✅ | Версия в формате semver |
description | string | ❌ | Описание модуля |
authors | array | ❌ | Список авторов |
url | string | ❌ | URL проекта |
providers | array | ✅ | Классы провайдеров |
dependencies | object | ❌ | Зависимости модуля |
Провайдеры
Один провайдер
Большинство модулей имеют один провайдер:
{
"providers": [
"Flute\\Modules\\Blog\\Providers\\BlogProvider"
]
}Множественные провайдеры
Для сложных модулей можно разделить логику на несколько провайдеров:
{
"providers": [
"Flute\\Modules\\Shop\\Providers\\ShopProvider",
"Flute\\Modules\\Shop\\Providers\\ShopAdminProvider",
"Flute\\Modules\\Shop\\Providers\\ShopApiProvider"
]
}Приоритет провайдеров
Можно задать порядок загрузки через объект с order:
{
"providers": [
{ "class": "Flute\\Modules\\Core\\Providers\\CoreProvider", "order": 10 },
{ "class": "Flute\\Modules\\Core\\Providers\\PluginsProvider", "order": 20 }
]
}Провайдеры сортируются по order независимо от позиции в массиве. Меньшее значение — раньше загрузка.
Виды зависимостей
Версия PHP
{
"dependencies": {
"php": ">=8.2"
}
}Поддерживаемые операторы:
>=— больше или равно>— строго больше<=— меньше или равно<— строго меньше==— равно!=— не равно
Версия Flute CMS
{
"dependencies": {
"flute": ">=1.0.0"
}
}Зависимости от других модулей
Если ваш модуль требует другие модули для работы:
{
"dependencies": {
"modules": {
"Payments": ">=1.0.0",
"Notifications": ">=1.0.0",
"Users": ">=2.0.0"
}
}
}При отсутствии или неверной версии зависимого модуля ваш модуль будет автоматически отключён.
PHP расширения
{
"dependencies": {
"extensions": [
"gd",
"mbstring",
"curl",
"zip",
"intl"
]
}
}Composer пакеты
{
"dependencies": {
"composer": {
"intervention/image": "^2.7",
"laravel/socialite": "^5.5",
"guzzlehttp/guzzle": "^7.0"
}
}
}Composer пакеты проверяются через InstalledVersions. Автоматическая установка не выполняется — пакеты нужно добавить в основной composer.json проекта.
Зависимости от темы
{
"dependencies": {
"theme": {
"standard": ">=1.0.0"
}
}
}Как работает система зависимостей
Инициализация
При старте ModuleManager проверяет зависимости каждого активного модуля. Хеш состояния кешируется на час.
Проверка
Проверяются все типы зависимостей: PHP, Flute, модули, расширения, Composer, тема.
Авто-отключение
При ошибке зависимостей модуль автоматически переводится в статус disabled, кеш пересобирается.
Ручная проверка зависимостей
В провайдере модуля можно добавить дополнительные проверки:
<?php
namespace Flute\Modules\Blog\Providers;
use Flute\Core\Support\ModuleServiceProvider;
class BlogProvider extends ModuleServiceProvider
{
public function boot(\DI\Container $container): void
{
$this->checkDependencies();
$this->bootstrapModule();
}
protected function checkDependencies(): void
{
// Проверка наличия модуля
if (!modules()->issetModule('Payments')) {
logs('blog')->warning('Модуль Payments не найден. Некоторые функции отключены.');
}
// Проверка версии модуля
$module = modules()->getModule('Payments');
if ($module && version_compare($module->version, '1.0.0', '<')) {
logs('blog')->error('Требуется Payments версии >= 1.0.0');
}
// Проверка PHP расширения
if (!extension_loaded('gd')) {
logs('blog')->warning('Расширение GD не загружено. Обработка изображений отключена.');
}
}
}Версионирование
Семантическое версионирование (SemVer)
MAJOR.MINOR.PATCH
Примеры:
1.0.0 — стабильный релиз
1.1.0 — новая функциональность (обратно совместимая)
1.0.1 — исправление багов
2.0.0 — несовместимые изменения API
1.0.0-beta — бета-версия
1.0.0-rc.1 — релиз-кандидатПравила:
- MAJOR — при несовместимых изменениях API
- MINOR — при добавлении функциональности с сохранением совместимости
- PATCH — при исправлении багов
Практические примеры
Простой модуль без зависимостей
{
"name": "Blog",
"version": "1.0.0",
"description": "Простой модуль блога",
"authors": ["Разработчик"],
"providers": [
"Flute\\Modules\\Blog\\Providers\\BlogProvider"
],
"dependencies": {
"php": ">=8.2",
"flute": ">=1.0.0"
}
}Модуль с зависимостью от другого модуля
{
"name": "Shop",
"version": "1.2.1",
"description": "Модуль интернет-магазина",
"authors": ["Команда"],
"providers": [
"Flute\\Modules\\Shop\\Providers\\ShopProvider"
],
"dependencies": {
"php": ">=8.2",
"flute": ">=1.0.0",
"modules": {
"GiveCore": ">=1.0.0"
}
}
}Модуль с Composer зависимостями
{
"name": "ImageGallery",
"version": "1.0.0",
"description": "Галерея изображений",
"providers": [
"Flute\\Modules\\ImageGallery\\Providers\\GalleryProvider"
],
"dependencies": {
"php": ">=8.2",
"flute": ">=1.0.0",
"extensions": ["gd"],
"composer": {
"intervention/image": "^2.7"
}
}
}Диагностика ошибок
Типичные ошибки и решения
Модуль не найден
Module "Blog" dependency check failed - Module "Payments" version 1.0.0 or higher is requiredРешение: Установите или обновите требуемый модуль Payments.
Программная диагностика
<?php
use Flute\Core\ModulesManager\ModuleManager;
$moduleManager = app(ModuleManager::class);
// Получение информации о модуле
$module = $moduleManager->getModule('Blog');
echo "Статус: " . $module->status;
echo "Версия: " . $module->version;
// Проверка существования
if ($moduleManager->issetModule('Payments')) {
echo "Модуль Payments установлен";
}
// Получение активных модулей
$activeModules = $moduleManager->getActive();
foreach ($activeModules as $name => $info) {
echo "{$name}: {$info->version}";
}Лучшие практики
Минимизируйте зависимости
Указывайте только действительно необходимые модули и пакеты.
Используйте диапазоны версий
>=1.0.0 вместо точной версии 1.0.0 для большей совместимости.
Документируйте зависимости
В README модуля опишите, зачем нужны те или иные зависимости.
Тестируйте совместимость
Проверяйте работу модуля с разными версиями зависимостей.
Следуйте SemVer
Используйте семантическое версионирование для своих модулей.