Issue: yiisoft/config#72
В текущей реализации все дефолтные конфигурационные файлы, которые расположены в вендоре в соответствующих пакетах,
копируются в приложение автоматически при установке приложения (composer <create-project|install|update>
).
Таким образом все конфигурации пакетов контролирует пользователь.
Предлагается не копировать конфигурации в приложение, а оставлять их в вендоре. Если же пользователю нужно будет переопределить конфигурацию пакета, то он скопирует файлы из вендора (используя консольную команду) в приложение и переопределит. Команда будет выглядеть следующим образом:
// Копировать конфигурацию одного пакета.
composer yii-config-copy yiisoft/aliases
// Копировать конфигурации нескольких пакетов.
composer yii-config-copy yiisoft/aliases yiisoft/view
Плюсы:
- Не нужно самостоятельно копировать файлы, они уже скопированы и разложены по папкам с названиями пакетов.
- Полный контроль над всеми файлами конфигураций, если при обновлении пакетов, конфигурация новой версии пакета
изменилась, то будут предложены действия:
- "Игнорировать, ничего не делать."
- "Заменить локальную версию файла новой версией."
- "Скопировать новую версию файла с постфиксом
.dist
." - "Вывести diff-файлов в консоль."
Минусы:
- Большое количество файлов конфигураций в приложении.
- Все дефолтные файлы конфигураций хранятся в приложении и визуально не понятно, что в приложении
сконфигурировано кастомно (для этого нужно вызвать
composer config-diff
).
Плюсы:
- Действия для измененных файлов при обновлении пакета, будут предложены только для переопределенных конфигураций, а дефолтные файлы в вендоре будут перезаписываться автоматически.
- Все дефолтные конфигурационные файлы находятся в вендоре, а в приложении только переопределенные. Визуально мало файлов. Проще ориентироваться. Легко понять, что именно сконфигурировано в приложении.
Минусы:
- Меньше контроля над файлами.
- Дефолтные конфигурации в вендоре будут перезаписаны при обновлении пакета и могут возникать конфликты с кодом приложения.
- Пользователь может не использовать консольную команду для копирования файлов из вендора, а скопировать их вручную,
таким образом служебная информация о конфигурациях в
dist.lock
иmerge_plan.php
не обновится.
Глобальные зменения:
- Все дефолтные конфигурационные файлы находятся в вендоре, а в приложении только переопределенные.
- Добавлена команда
yii-config-copy
для копирования конфигурационных файлов из вендора в приложение. - Добавлена команда
yii-config-rebuild
для обновления плана слияния. - Удален параметр
output-directory
, осталась толькоsource-directory
для всех пакетов. - Удален весь интерактив и отслеживание изменений файлов.
- Удалена папка
config/packages
и файлdist.loc
. - План слияния перенесен в папку
config
.
Конфигурации загружаются следующим образом:
- Сначала загружаются дефолтные конфигурации пакетов из вендора.
- Затем загружаются конфигурации корневого пакета.
- Если есть совпадение ключей, то конфигурация корневого пакета перезапишет конфигурацию пакета из вендора.
Полноценного слияния также не происходит. Существует три слоя: пакеты из вендора, корневой пакет (приложение) и окружения приложения. Одинаковые ключи могут быть в разных слоях, но если в пакетах из вендора или корневой пакете, или в окружениях приложения есть совпадение ключей, то будет брошено исключение о дубликате ключей.
В текущей реализации в подавляющем большинстве, нужно переопределить один ключ, в логгере например, это реализация
Psr\Log\LoggerInterface
, из-за этого в приложение копируется все конфиг-файлы пакета. В альтернативной реализации,
он может в любом конфиг-файле приложения переопределить только реализацию интерфейса, а все остальное подтянется
из вендора.
При таком подходе у пользователя практически нет ограничений не в чем. Он сможет создать любую структуру папок. Пользователь может копировать куски кода вручную (как в Yii2 было) или использовать команду. Работать будет и так и так.
Команда копирует файлы конфигурации пакета от поставщика в каталог конфигурации корневого пакета (приложения):
composer yii-config-copy <package-name> [target-path] [files]
Копирует все файлы конфигурации пакета yiisoft/view
:
# To the `config` directory
composer yii-config-copy yiisoft/view
# To the `config/my/path` directory
composer yii-config-copy yiisoft/view my/path
Копирует указанные файлы конфигурации пакета yiisoft/view
:
# To the `config` directory
composer yii-config-copy yiisoft/view / params.php web.php
# To the `config/my/path` directory and without the file extension
composer yii-config-copy yiisoft/view my/path params web
Чтобы избежать конфликтов с именами файлов, к именам скопированных файлов добавляется префикс:
yiisoft-view-params.php
, yiisoft-view-web.php
.
Команда обходит все файлы конфигурации и обновляет файл плана слияния. Это может потребоваться, если в структуру файлов
конфигураций приложения добавлены файлы или папки, которые не были указаны в composer.json
корневого пакета.
Необходимо добавить в информацию о новых файлах в composer.json
корневого пакета и вызвать команду:
composer yii-config-rebuild
Вариант с тем чтобы оставить дефолтные конфиги в вендоре до тех пор пока не потребуется что-то переопределить, однозначно лучше затаскивания всех подряд конфигов в приложение, потому что будет меньше бессмысленных файлов, меньше мусора. Меньше файлов - проще приложение.
Название для команды спорное, что за "copy"? Что куда копируется? Название ничего не проясняет. Можно назвать "extract-config" или "publish-config" по примеру "vendor:publish" в Laravel: https://laravel.com/docs/8.x/packages#configuration
Вообще в Laravel более продуманная система, так как "публиковать" действительно может понадобиться не только конфиг, но и вьюхи с ассетами, допустим какой-то модуль с фронтенд частями предполагающими кастомизацию пользователем. На текущем этапе конечно можно ограничиться конфигом, но на будущее стоит иметь в виду.
Тут два варианта решения.
Вариант 1. Выкидываем вообще dist.lock и merge_plan - непонятно зачем они вообще нужны.
Вариант 2. Делаем команду для ручного обновления при необходимости, а также делаем команду, которая проверяет что эти файлы рассинхронизированы и требуют обновления. Если это покажется целесообразным, можно даже запускать команду проверки в CI или при каждом старте консольного приложения в DEV-окружении.
Я конечно за то чтобы выкинуть и merge_plan и dist.lock. Можно прекрасно обойтись без них, как обходится и Yii2 и любой другой фреймворк.