Spec-Zone.ru › Yarn 3

Ограничения

Экспериментальная функция

Эта функция ещё находится в стадии разработки, и её точный API может меняться от релиза к релизу. Это означает, что сейчас идеальное время для вашего участия и предоставления отзывов!

Плагин

Для доступа к этой функции сначала установите плагин constraints: yarn plugin import constraints

Ограничения — это решение очень простой задачи: у меня много рабочих пространств, и мне нужно убедиться, что они используют одну и ту же версию зависимостей. Или что они не зависят от определённого пакета. Или что они используют определённый тип зависимостей. В любом случае, вы понимаете суть: какова бы ни была точная логика, моя цель остаётся неизменной; я хочу автоматически применить какой-либо набор правил ко всем моим рабочим пространствам. Именно это и позволяют сделать ограничения.

  • Создание ограничения

    • Предикат запроса

      • dependency_type/1
      • workspace/1
      • workspace_ident/2
      • workspace_version/2
      • workspace_has_dependency/4
      • workspace_field/3
    • workspace_field_test/3

    • Предикаты ограничений

      • gen_enforced_dependency/4
      • gen_enforced_field/3
  • Рецепты ограничений

    • Запретить всем рабочим пространствам зависимость от определённого пакета
    • Запретить двум рабочим пространствам зависимость от конфликтующих версий одной и той же зависимости
    • Принудительно сделать все зависимости рабочих пространств явными

Создание ограничения

Ограничения создаются путём добавления файла constraints.pro в корень вашего проекта (репозитория). Расширение .pro может вас сбить с толку: это потому, что ограничения не написаны на JavaScript (!), а на языке Prolog, фактоориентированной системе правил. Цель этого раздела — не научить вас Prolog (хорошие учебники уже существуют, например, Learn Prolog in Y Minutes), а показать, почему мы выбрали именно его и какую ценность он несёт.

Как мы уже упоминали, Prolog — это фактоориентированная система. Она начинается со списка *фактов*, которые всегда истинны, и списка *предикатов*, которые по сути читаются как «предикат f(X) истинен, если u(X) и v(X) оба истинны». Вычисляя, для каких значений X предикаты u(X) и v(X) истинны, Prolog может автоматически вычислить список значений, для которых f(X) будет истинно. Это особенно полезно для ограничений, потому что позволяет писать очень простые, но мощные правила, которые могут повлиять на все ваши рабочие пространства всего в нескольких строках.

Возвращаясь к системе ограничений, *факты* — это определения, созданные менеджером пакетов (например, «факт: корневое рабочее пространство зависит от Lodash версии 4.4.2 в devDependencies»), а *предикаты* — это набор правил, которые вы хотите применить ко всему вашему проекту (ниже приведены некоторые рецепты).

Предикат запроса

Следующие предикаты предоставляют информацию о текущем состоянии вашего проекта и предназначены для использования в зависимостях ваших собственных правил (см. рецепты для примеров практического использования). Обратите внимание, что синтаксис /<number> в конце просто обозначает арность предиката (количество аргументов, которые он принимает).

В этой документации для параметров предикатов используются префиксы -, + и ?. Эти значения широко используются в документации Prolog и означают

  • +: это значение рассматривается как входное и должно быть инстанцировано
  • -: это значение рассматривается как выходное и будет инстанцировано предикатом, хотя вы можете предоставить значение для проверки соответствия
  • ?: это значение может быть инстанцировано или нет, оба варианта подойдут

dependency_type/1

dependency_type(
  -DependencyType
).

Истина только для трёх значений: dependencies, devDependencies и peerDependencies.

workspace/1

workspace(
  -WorkspaceCwd
).

Истина, если рабочее пространство, описанное указанным WorkspaceCwd, существует.

workspace_ident/2

workspace_ident(
  ?WorkspaceCwd,
  ?WorkspaceIdent
).

Истина, если рабочее пространство, описанное указанным WorkspaceCwd, существует и если оно имеет указанную WorkspaceIdent.

workspace_version/2

workspace_version(
  ?WorkspaceCwd,
  ?WorkspaceVersion
).

Истина, если рабочее пространство, описанное указанным WorkspacedCwd, существует и если оно имеет указанную WorkspaceVersion.

workspace_has_dependency/4

workspace_has_dependency(
  ?WorkspaceCwd,
  ?DependencyIdent,
  ?DependencyRange,
  ?DependencyType
).

Истина, если рабочее пространство, описанное указанным WorkspaceCwd, зависит от зависимости, описанной указанным сочетанием DependencyIdent и DependencyRange, в блоке зависимостей данного DependencyType.

workspace_field/3

workspace_field(
  +WorkspaceCwd,
  +FieldPath,
  -FieldValue
).

Истина, если рабочее пространство, описанное WorkspaceCwd, имеет заданное FieldValue в манифесте по адресу FieldPath.

FieldPath может указывать на свойства свойств с помощью обозначения ., например, FieldPath 'publishConfig.registry' установит FieldValue в значение registry внутри publishConfig.

workspace_field_test/3

workspace_field(
  +WorkspaceCwd,
  +FieldPath,
  +CheckCode
).

Истина, если рабочее пространство, описанное WorkspaceCwd, имеет значение в манифесте по адресу FieldPath, и если это значение проходит проверку CheckCode.

Скрипт CheckCode предназначен для написания на JavaScript, с особой переменной $$, представляющей значение, полученное из манифеста. Это делает workspace_field_test способом выхода из ситуации для некоторых операций, которые были бы слишком неудобны для реализации на Prolog (например, проверка наличия значения в массиве JS и т. д.).

Параметр Arguments ожидается как необязательный список Prolog атомов, которые будут переданы в CheckCode, $1 и т.д.

Предикаты ограничений

Следующие предикаты повлияют на поведение команд yarn constraints и yarn constraints --fix.

Параметры предикатов имеют префиксы + и -. Они имеют то же значение, что и в предикатных запросах. В этом контексте они означают

  • - Выходные данные, они не будут иметь значения при вызове предиката, и предикат должен гарантировать установление значения
  • + Входные данные, они уже будут иметь значение при вызове предиката

gen_enforced_dependency/4

gen_enforced_dependency(
  +WorkspaceCwd,
  -DependencyIdent,
  -DependencyRange,
  +DependencyType
).

Правило gen_enforced_dependency предлагает удобный способ информировать менеджер пакетов о том, что определённое рабочее пространство ДОЛЖНО зависеть от определённого диапазона определённой зависимости (если DependencyRange не равно нулю) или не зависеть от неё вообще (если DependencyRange равно нулю; имеет приоритет перед любым конфликтным диапазоном) в блоке зависимостей DependencyType.

Выполнение команды yarn constraints --fix укажет Yarn на исправление обнаруженных ошибок наилучшим способом, но в некоторых случаях могут возникнуть неоднозначности. Их нужно будет решить вручную, хотя Yarn вам в этом поможет.

gen_enforced_field/3

gen_enforced_field(
  +WorkspaceCwd,
  -FieldPath,
  +FieldValue
).

Предикат gen_enforced_field сообщает менеджеру пакетов, что определённое рабочее пространство должно иметь указанное FieldValue в манифесте через FieldPath. FieldValue null означает, что поле должно отсутствовать:

? gen_enforced_field(WorkspaceCwd, FieldPath, null).

Обратите внимание, что значение будет интерпретироваться как JSON, если это возможно, или как обычная строка в противном случае. Таким образом, если вам нужно поместить значение null в поле, используйте синтаксис JSON:

? gen_enforced_field(WorkspaceCwd, FieldPath, 'null').

Наконец, если вам нужно поместить строку, содержащую null, в поле, используйте синтаксис JSON-строки:

? gen_enforced_field(WorkspaceCwd, FieldPath, '"null"').

Выполнение команды yarn constraints --fix укажет Yarn на исправление обнаруженных ошибок наилучшим способом, но в некоторых случаях могут возникнуть неоднозначности. Их нужно будет решить вручную, хотя Yarn вам в этом поможет.

Рецепты ограничений

Следующие ограничения — хорошая отправная точка для того, чтобы понять, как написать собственные правила. Если вы создадите правило, которое, по вашему мнению, подойдёт для этой секции, откройте PR, и мы добавим его сюда!

Быстрое замечание по синтаксису Prolog

Помните, что в Prolog X :- Y по сути означает «X истинно для каждого Y, которое истинно». Также знайте, что имена в UpperCamelCase — это переменные, которые «заменяются» всеми совместимыми значениями. Наконец, специальное имя переменной _ просто отбрасывает значение параметра.

Запретить всем рабочим пространствам зависимость от определённого пакета

gen_enforced_dependency(WorkspaceCwd, 'tslib', null, DependencyType) :-
  workspace_has_dependency(WorkspaceCwd, 'tslib', _, DependencyType).

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

Предотвращение зависимости двух рабочих пространств от конфликтующих версий одной и той же зависимости

gen_enforced_dependency(WorkspaceCwd, DependencyIdent, DependencyRange2, DependencyType) :-
  workspace_has_dependency(WorkspaceCwd, DependencyIdent, DependencyRange, DependencyType),
  workspace_has_dependency(OtherWorkspaceCwd, DependencyIdent, DependencyRange2, DependencyType2),
  DependencyRange \= DependencyRange2.

Мы определяем gen_enforced_dependency правило, которое требует, чтобы каждая зависимость каждого пакета (первый workspace_has_dependency) имела, если также существует другая зависимость другого пакета (второй workspace_has_dependency) с тем же именем, но с другим диапазоном (\= оператор).

Принудительная явность всех зависимостей рабочего пространства

gen_enforced_dependency(WorkspaceCwd, DependencyIdent, 'workspace:*', DependencyType) :-
  workspace_ident(_, DependencyIdent),
  workspace_has_dependency(WorkspaceCwd, DependencyIdent, _, DependencyType).

Мы определяем gen_enforced_dependency правило, которое требует использования диапазона зависимостей workspace:*, если имя зависимости также является именем допустимого рабочего пространства. Последняя workspace_has_dependency проверка гарантирует, что это правило применяется только к тем рабочим пространствам, которые в настоящее время зависят от указанного рабочего пространства в первую очередь (если бы её не было, правило вместо этого заставило бы все рабочие пространства зависеть друг от друга).

© 2016–present Yarn Contributors
Licensed under the BSD License.
https://v3.yarnpkg.com/features/constraints

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API