Подтвердить что ты не робот

Как свойство "replace" работает с композитором?

Итак, как работает свойство replace с composer? Я прочитал документ композитора, но все еще не понимаю. Поиск дополнительной информации не ответил на мои вопросы.

Когда я смотрю файл composer.json на Laravel/Framework на github. Я не вижу, как будет работать замена. Может ли кто-нибудь объяснить мне, как это работает? И какая переменная "self.version" будет равна?

4b9b3361

Ответ 1

Документация Composer дает два основных примера. Я постараюсь объяснить:

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

Предположим, что ваше программное обеспечение использует original/library и other/package, для которого также требуется original/library.

Теперь вы думаете, что original/library должны интегрировать функцию, но сопровождающие не допустят, чтобы ваше предложение появилось в их пакете. Вы решаете раскошелиться на эту библиотеку под именем better/library и отметить новую версию.

Вернуться к вашему программному обеспечению. Конечно, он должен начать использовать better/library, так что вместо этого вам нужно, но этот other/package все еще требует original/library - дублирование кода! Как вы можете заставить этот другой пакет использовать вашу better/library вместо этого, не разветвляя ее и только изменяя composer.json (вы все еще совместимы с этим original/library, поэтому он должен работать)?

Вы добавляете ключ замены в ваш composer.json:

"replace": {
    "original/library":"1.0.2"
}

Теперь Composer знает, что любой пакет из вашей better/library одинаково хорош как original/library когда дело доходит до разрешения зависимостей other/package.

Это также полезно для пакетов, которые содержат подпакеты, например, основной пакет symfony/symfony содержит все компоненты Symfony, которые также доступны в виде отдельных пакетов. Если вам требуется основной пакет, он автоматически выполнит любое требование одного из отдельных компонентов, поскольку он заменяет их.

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

Осторожно: заполнители в замененных версиях обычно плохие

В своем первоначальном ответе я предложил:

"replace": {
    "original/library":"1.*"
}

Это имеет последствия: Composer теперь будет рассматривать вашу библиотеку версии 1.0.0 так же хорошо, как ЛЮБУЮ версию 1.x оригинальной библиотеки, даже если они исправят вещи или добавят функции и выпустят версию 1.2.34 когда-нибудь. Это также означает, что если ваш other/package нибудь получит обновление и требует original/library:^1.1, замена в ВАШЕЙ библиотеке все еще активна и заявляет, что она может заменить ЛЮБУЮ версию 1.*, даже если вы ничего не обновляете внутри - что это невозможно, ваш старый код никогда не будет реализовывать новые функции исходной библиотеки, если вы не проделаете какую-то работу, но замена говорит именно об этом.

Итак, по сути: избегайте подстановочных версий в заменяющей версии! Если вы используете их, вы делаете выражение о будущем, которое вы не можете знать или предсказать (если вы не можете контролировать original/library, но даже тогда будьте очень осторожны). Всегда используйте конкретную версию original/library которую вы знаете и можете полностью реализовать заново.

Ответ 2

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

Если вы используете свойство replace, оно сообщает Composer, что ваш пакет хочет заменить исходный пакет своим собственным форком, поэтому другим пакетам не нужно его устанавливать.

Например, если пакет a/a требует b/b и вы указываете заменить b/b, он не будет загружен при install/update Composer.

Это объясняется более подробно здесь: Как работает свойство "заменить" в Composer?

Как работает