n1ro°
RU

Текст и данные · Инструкция

Yarn patch: как исправить зависимость без форка

Yarn patch позволяет локально изменить установленную зависимость, сохранить diff как patch-файл в проекте и заставить.

Редакция N1RO · Проверено

Короткий ответ

Запустите `yarn patch <package>`, отредактируйте распакованную копию в указанной временной директории, затем выполните `yarn patch-commit -s <directory>`. Закоммитьте созданный patch-файл вместе с manifest/lockfile и добавьте тест, который доказывает, что локальная правка действительно нужна.

Когда patch лучше форка, а когда нет

Patch удобен для маленькой целевой правки в стороннем пакете: например, одной строки совместимости, небольшого defensive-check или временного исправления до upstream-релиза. Он хранит только diff, поэтому проект не несёт отдельный fork и остаётся ближе к официальной зависимости. Но patch — не универсальная замена форку. Если изменение затрагивает много файлов, требует отдельного build-процесса, генерирует артефакты или живёт месяцами как самостоятельная ветка разработки, fork обычно прозрачнее. Официальная документация Yarn также подчёркивает, что patch применяется после разрешения зависимости и не предназначен для изменения dependency metadata самого пакета; если нужно скорректировать зависимости/peerDependencies, для этого существуют другие механизмы конфигурации. Поэтому перед созданием patch сформулируйте минимальный diff и причину. Чем меньше патч, тем проще заметить, когда новая версия upstream уже содержит исправление.

Совет: Добавьте рядом с patch короткий комментарий в PR или issue-ссылку на upstream. Через несколько месяцев это помогает понять, можно ли удалить локальную правку.

Рабочий процесс yarn patch

  1. Зафиксируйте исходную проблему: Сначала сделайте тест или минимальный reproduction на текущей версии пакета. Без него трудно понять, нужен ли patch после обновления.
  2. Откройте пакет через `yarn patch`: Выполните `yarn patch <package>`. Yarn распакует пакет во временную директорию и напечатает путь, который нужно редактировать.
  3. Измените только необходимое: Отредактируйте минимальный набор файлов. Не вносите косметические форматирования по всему пакету — они увеличивают diff и усложняют future rebase.
  4. Сохраните patch: Запустите `yarn patch-commit -s <temporary-directory>`. Опция `-s/--save` создаёт patch-файл и регистрирует его в верхнеуровневом manifest через `patch:` protocol.
  5. Проверьте чистую установку: Удалите локальные артефакты, которые могут скрывать ошибку, и выполните обычную установку проекта. Тест должен проходить именно потому, что Yarn применил сохранённый patch.
  6. Закоммитьте связанные изменения: В репозиторий должны попасть patch-файл и изменения manifest/lockfile, созданные Yarn, чтобы CI и другие разработчики получили тот же результат.

Важно: Не редактируйте временную директорию после `patch-commit` в расчёте, что изменения «подхватятся сами». Источником истины для проекта становится сохранённый patch-файл.

Как обновить уже существующий patch

Когда patch уже зарегистрирован, а вам нужно добавить ещё одну правку, официальный CLI поддерживает `yarn patch -u <package>` или `--update`. В этом режиме Yarn снова открывает редактируемую директорию с текущим патчем уже применённым, чтобы не собирать diff с нуля. После изменений снова используйте `yarn patch-commit -s` для сохранения обновлённой версии. Такой подход особенно полезен, если первоначальный patch небольшой и эволюционировал на один дополнительный edge case. При этом review всё равно должен рассматривать итоговый patch целиком, а не только вторую правку: накопленные изменения могут начать скрывать то, что пакет пора обновить или форкнуть. После обновления обязательно прогоните clean install и тесты на CI. Если новая upstream-версия изменила строки рядом с патчем, применение может конфликтовать; это полезный сигнал вручную проверить, сохранилась ли исходная проблема.

Что проверять в code review

Patch-файл — часть production dependency chain, поэтому относитесь к нему как к обычному исходному коду. В review проверьте, что diff минимален, нет случайных generated-файлов, отладочных логов и секретов, а причина изменения подтверждается тестом. Сверьте версию/locator пакета, к которому относится patch, и убедитесь, что lockfile изменён ожидаемо. Полезно проверить clean checkout: установить зависимости с нуля и запустить тест без локального Yarn cache, если инфраструктура позволяет. Отдельно оцените безопасность: патч в vendor-коде может обходить upstream-проверку или менять поведение в месте, которое затем обновится. Если исправление связано с security issue, следите за upstream-релизом и удалите patch после перехода на официальную исправленную версию. Наконец, не храните бинарные или огромные generated diffs в patch без крайней необходимости: это ухудшает review и делает конфликты при обновлении почти неизбежными.

Предупреждение: Patch должен быть временно объяснимым. Если никто в команде не может за минуту ответить, зачем он существует и каким тестом защищён, это уже долг по сопровождению.

Как понять, что patch пора удалить

Лучший жизненный цикл patch заканчивается удалением. Когда выходит новая версия зависимости, сначала проверьте changelog или upstream issue, затем попробуйте обновиться без локального patch и запустить reproduction-тест. Если исправление уже вошло upstream, оставленный patch становится риском: он может повторно менять уже исправленный код или конфликтовать с новой реализацией. Если upstream выбрал другой дизайн, сравните поведение, а не просто строки diff. Удаление нужно делать так же аккуратно: убрать `patch:` reference/связанные записи через Yarn-механизм, обновить lockfile и выполнить clean install. Если же patch не удаётся удалить много релизов подряд и он постоянно перерабатывается, это аргумент в пользу более явной стратегии — форка, собственного wrapper-пакета или смены зависимости. Patch хорош именно тогда, когда разница мала, локальна и понятна.

Как документировать patch, чтобы его можно было удалить

Хороший patch должен объяснять собственный срок жизни. Рядом с изменением зафиксируйте locator пакета, причину локальной правки, ссылку на upstream issue или pull request и тест, который падает без патча. Не включайте эту служебную информацию в сам vendor-diff, если она не нужна коду: удобнее держать её в commit message, changelog проекта или комментарии рядом с dependency configuration. При каждом обновлении пакета сначала проверяйте, применяется ли patch вообще и сохраняется ли исходная проблема. Yarn `patch-commit -s` сохраняет патч в локальный файл и добавляет resolution в верхнеуровневый manifest; это делает зависимость воспроизводимой, но не снимает обязанность пересматривать её. Если patch регулярно конфликтует с новыми версиями, растёт или требует всё новых исключений, это уже сигнал сменить стратегию на fork, wrapper или другой пакет, а не бесконечно наращивать локальный diff.

Перед merge patch

  • Есть reproduction или тест исходной проблемы
  • Diff минимален и не содержит посторонних форматирований
  • Использован `patch-commit -s` и patch сохранён в проекте
  • Manifest и lockfile обновлены ожидаемо
  • Clean install применяет patch без ручных действий
  • Есть ссылка/контекст для будущего удаления patch

Что учитывать

Условия меняются. Страница отражает состояние на 2026-09-21; при расхождении с официальной документацией приоритет у первоисточника.

Источники и проверка

Фактическая часть сверена по первичным источникам (в т.ч. yarn patch). Пример и формулировки — редакция N1RO на 2026-09-21.