5. Миграция
Любая крупная версия имеет свои изменения, нарушающие совместимость, и Yarn 2 не является исключением. Несколько старых поведений были очищены, исправлены, изменены или удалены. Хотя одной из наших целей является упрощение перехода, есть несколько моментов, о которых следует помнить при миграции кодовой базы. Чтобы сделать этот процесс более эффективным, ниже приведены рекомендуемые шаги по миграции, а также решения наиболее распространённых проблем, с которыми вы можете столкнуться.
-
- Обновление до Node.js 12.x или более поздней версии
- Исправление зависимостей с
packageExtensions - Использование
yarn dlxвместоyarn global - Включение плагина PnP при использовании Webpack 4
- Обновление
resolveдо 1.9+ - Вызов бинарных файлов с помощью
yarn runвместоnode_modules/.bin - Вызов скриптов через
yarn nodeвместоnode - Явное вызов скриптов
preиpost - Настройка вашей IDE для поддержки PnP
- Обновление вашей конфигурации до новых настроек
- Не использовать файлы
.npmrc - Ознакомьтесь с нашими end-to-end тестами
- Не использовать
bundleDependencies - При необходимости: включить плагин
node-modules - Заменить
nohoistнаnmHoistingLimits
Почему стоит мигрировать?
Мы подробно отвечаем на этот вопрос здесь.
Коротко, обновление до последних версий крайне важно для быстрого и стабильного использования Yarn. С момента первой крупной версии было исправлено множество ошибок, и мы больше не ожидаем добавления новых функций в старый ствол. Даже если вы не планируете использовать новую стратегию установки по умолчанию, называемую Plug'n'Play, ваши проекты всё равно получат преимущества от обновления:
- Улучшен старинный установщик
node_modules, а также исправлены различные крайние случаи - Новое внимание к производительности и лучшим практикам (мы теперь формально отслеживаем производительность через панель мониторинга)
- Улучшен пользовательский интерфейс для различных команд и настроек CLI (
yarn add -i,yarn up,logFilters, ...) - Новые команды и возможности (такие как плагин TypeScript или рабочий процесс выпуска)
И, конечно же, очень активный цикл разработки.
Пошаговая инструкция
Примечание: Не волнуйтесь, если ваш проект пока не готов к Plug'n'Play! Это руководство позволит вам мигрировать, не потеряв папку node_modules. Только в последующем необязательном разделе мы рассмотрим, как включить поддержку PnP, и эта часть будет лишь рекомендацией, а не обязательным пунктом. Маленькие шажки! 😉
Обратите внимание, что эти команды нужно выполнить только один раз для всего проекта, и они автоматически вступят в силу для всех ваших участников сразу после того, как они получат коммит миграции, благодаря силе yarnPath:
- Запустите
npm install -g yarn, чтобы обновить глобальную версию yarn до последней v1 - Перейдите в каталог своего проекта
- Запустите
yarn set version berry, чтобы включить v2 (см. Установку для более подробной информации) - Если вы использовали
.npmrcили.yarnrc, вам нужно будет преобразовать их в новый формат (см. также 1, 2) - Добавьте
nodeLinker: node-modulesв свой файл.yarnrc.yml - Зафиксируйте внесённые изменения (
yarn-X.Y.Z.js,.yarnrc.yml, ...) - Запустите
yarn install, чтобы мигрировать файл блокировки - Ознакомьтесь со статьёй о том, какие файлы следует игнорировать в системе контроля версий
- Зафиксируйте оставшиеся изменения
Некоторые дополнительные возможности доступны через внешние плагины:
- Запустите
yarn plugin import interactive-tools, если вам нужнаupgrade-interactive - Запустите
yarn plugin list, чтобы увидеть другие официальные плагины, которые могут быть полезны - Зафиксируйте плагины yarn
Теперь у вас должна быть работающая установка Yarn! Некоторые вещи могут всё ещё потребовать дополнительной работы (например, мы устарели произвольными скриптами жизненного цикла, и переименовали --frozen-lockfile в --immutable), но эти особые случаи будут документированы на индивидуальной основе в остальной части этого документа (например, здесь).
Переход к Plug'n'Play
Этот шаг совершенно необязателен — хотя мы рекомендуем использовать Plug'n'Play для большинства новых проектов, иногда может потребоваться немало времени, чтобы включить его в существующие проекты. По этой причине мы предпочитаем вынести его сюда как отдельный шаг, который вы можете изучить, если вы заинтересованы или просто хотите получить максимальную отдачу от Yarn.
Перед началом
Plug'n'Play применяет строгие правила зависимостей. В частности, у вас возникнут проблемы, если вы (или ваши зависимости) полагаетесь на не указанные зависимости (причины этого подробно описаны в нашем Руководстве по правилам), но суть в том, что это была причина многих проблем "проект не работает на моём компьютере" как в Yarn, так и в других менеджерах пакетов.
Чтобы быстро обнаружить места, которые могут использовать небезопасные паттерны, запустите yarn dlx @yarnpkg/doctor в своём проекте — он статически проанализирует ваши источники, пытаясь найти наиболее распространённые проблемы, которые могут привести к низкой производительности. Например, вот что webpack-dev-server выявит:
➤ YN0000: Found 1 package(s) to process
➤ YN0000: For a grand total of 236 file(s) to validate
➤ YN0000: ┌ /webpack-dev-server/package.json
➤ YN0000: │ /webpack-dev-server/test/testSequencer.js:5:19: Undeclared dependency on @jest/test-sequencer
➤ YN0000: │ /webpack-dev-server/client-src/default/webpack.config.js:12:14: Webpack configs from non-private packages should avoid referencing loaders without require.resolve
➤ YN0000: │ /webpack-dev-server/test/server/contentBase-option.test.js:68:8: Strings should avoid referencing the node_modules directory (prefer require.resolve)
➤ YN0000: └ Completed in 5.12s
➤ YN0000: Failed with errors in 5.12sВ этом случае доктор заметил, что:
testSequencer.jsзависит от пакета, не указанного как соответствующая зависимость — что будет сообщаться как ошибка при запуске в Plug'n'Play.webpack.config.jsссылается на загрузчик, не передавая его имя вrequire.resolve— что небезопасно, так как это означает, что загрузчик не будет загружен из зависимостейwebpack-dev-servercontentBase-option.test.jsпроверяет содержимое папкиnode_modules— которой больше не будет в Plug'n'Play.
Включение
- Посмотрите в свой файл
.yarnrc.ymlна настройкуnodeLinker - Если вы её не найдёте или если она установлена в значение
pnp, значит всё в порядке: вы уже используете Plug'n'Play! - В противном случае удалите её из файла конфигурации
- Запустите
yarn install - Возможны новые файлы; обратитесь к статье об игнорировании файлов в системе контроля версий, чтобы понять, что следует добавить в gitignore
- Зафиксируйте внесённые изменения
Поддержка редакторов
У нас есть специальная документация, но если вы используете VSCode (или другую IDE с функцией типа Intellisense), то суть в следующем:
- Установите расширение VSCode ZipFS
- Убедитесь, что
typescript,eslint,prettier, ... все зависимости, обычно используемые расширениями вашей IDE, перечислены на верхнем уровне проекта (а не в случайном рабочем пространстве) - Запустите
yarn dlx @yarnpkg/sdks vscode - Зафиксируйте внесённые изменения — так у участников не будет необходимости проходить ту же процедуру
- Для TypeScript не забудьте выбрать Использовать версию рабочего пространства в VSCode
Заключительные замечания
Теперь у вас должна быть настроенная работающая установка Yarn Plug'n'Play, но ваш репозиторий, возможно, всё ещё нуждается в дополнительном уходе. Некоторые моменты, которые следует учитывать:
- Папка
node_modulesи папка.binбольше не существуют. Если вы полагались на них, используйтеyarn runвместо этого. - Замените все вызовы
node, которые не находятся внутри скрипта Yarn, наyarn node - Пользовательские пред-хуки (например, prestart) теперь необходимо вызывать вручную
Всё это и многое другое документировано в следующих разделах. В целом, мы рекомендуем на данном этапе попробовать запустить своё приложение и посмотреть, что сломается, а затем обратиться сюда, чтобы найти советы по исправлению вашей установки.
Общие рекомендации
Обновление до Node.js 12.x или более поздней версии
Node.js 10.x достиг официального конца жизненного цикла в апреле 2021 года и больше не будет получать обновлений. Вследствие этого Yarn больше не поддерживает его.
Исправление зависимостей с packageExtensions
Иногда пакеты забывают указать свои зависимости. В прошлом это приводило к множеству скрытых проблем, поэтому Yarn теперь по умолчанию предотвращает такие небезопасные обращения. Однако мы не хотим, чтобы это мешало вам выполнять свою работу, пока вы можете делать это безопасным и предсказуемым способом, поэтому мы разработали настройку packageExtensions.
Например, если react забыл указать зависимость от prop-types, вы исправите это так:
packageExtensions:
"react@*":
dependencies:
prop-types: "*"И если у плагина Babel отсутствовала зависимость peer от @babel/core, вы исправите это так:
packageExtensions:
"@babel/plugin-something@*":
peerDependencies:
"@babel/core": "*"
Используйте yarn dlx вместо yarn global
yarn dlx предназначен для выполнения одноразовых скриптов, которые могли быть установлены как глобальные пакеты с помощью yarn 1.x. Управление пакетами системы выходит за рамки yarn. Чтобы отразить это, yarn global было удалено. Подробнее на GitHub.
Включите плагин PnP при использовании Webpack 4
Webpack 5 поддерживает PnP в виде встроенной функции, но если вы используете Webpack 4, вам нужно добавить плагин pnp-webpack-plugin самостоятельно.
Обновите resolve до 1.9+
Пакет resolve используется многими инструментами для получения зависимостей для любой папки в файловой системе. Он совместим с Plug'n'Play, но только начиная с версии 1.9+, поэтому убедитесь, что в вашем дереве зависимостей нет более старых релизов (особенно в качестве транзитивной зависимости).
Решение: Откройте файл lockfile, найдите все записи resolve которые могут соответствовать версии 1.9+ (например, ^1.0.0) и удалите их. Затем снова выполните yarn install. Если вы запустите yarn why resolve, вы также получите представление о том, какой пакет зависит от устаревшей версии resolve — возможно, вам нужно обновить их тоже?
Вызывайте двоичные файлы с помощью yarn run вместо node_modules/.bin
Папка node_modules/.bin является деталью реализации, и PnP-установки ее вообще не генерируют. Вместо того, чтобы полагаться на ее существование, просто используйте команду yarn run, которая может запускать как скрипты, так и двоичные файлы:
yarn run jest
# or, using the shortcut:
yarn jest
Вызывайте свои скрипты через yarn node вместо node
Теперь нам нужно ввести некоторые переменные в среду, чтобы Node мог найти ваши зависимости. Для этого мы просим вас использовать yarn node, которая прозрачно выполняет основную работу.
Примечание: этот раздел применим только к командной строке. Команды, определённые в вашем файле scripts, не затрагиваются, так как мы гарантируем, что node всегда указывает на правильное местоположение с правильными переменными.
Явно вызывайте скрипты pre и post
Перепишите:
{
"scripts": {
"prestart": "do-something",
"start": "http-server"
}
}На:
{
"scripts": {
"prestart": "do-something",
"start": "yarn prestart && http-server"
}
}Примечание: Это относится только к пользовательским скриптам, таким как start и т.д. По-прежнему можно использовать любой из preinstall, install, и postinstall. Для получения дополнительной информации обратитесь к документации по скриптам.
Настройка IDE для поддержки PnP
Мы написали руководство, полностью предназначенное для объяснения использования Yarn с вашей IDE. Обязательно посмотрите на него, и, возможно, внесите свой вклад, если какие-то инструкции неясны или отсутствуют!
Обновите конфигурацию до новых настроек
Yarn 2 использует другой стиль файлов конфигурации, чем Yarn 1. Хотя в основном он незаметен для файла lockfile (потому что мы импортируем их на лету), это может вызвать некоторые проблемы для ваших файлов rc.
Основным изменением является имя файла. Yarn 1 использовал
.yarnrc, но Yarn 2 переходит к другому имени:.yarnrc.yml. Это должно облегчить сторонним инструментам определение, использует ли проект Yarn 1 или Yarn 2, и позволит легко настраивать разные параметры в ваших домашних каталогах при работе с набором проектов Yarn 1 и Yarn 2.Как видно из нового расширения файла, файлы Yarnrc теперь должны быть написаны в формате YAML. Это давно запрашивалось, и мы надеемся, что это позволит более простые интеграции для различных сторонних инструментов, которым необходимо взаимодействовать с файлами Yarnrc (например, Dependabot и т.д.).
-
Ключи конфигурации изменились. Полный список параметров доступен в нашей документации, но вот некоторые важные изменения, которые вам необходимо знать:
Настройка пользовательских репозиториев выполняется с помощью
npmRegistryServer.Токены аутентификации репозиториев настраиваются с помощью
npmAuthToken.yarn-offline-mirrorбыл удален, так как автономное зеркало было интегрировано в кэш в рамках проекта Zero-Install. Просто закоммитируйте кэш Yarn, и вы готовы к работе.
Не используйте файлы .npmrc
Помимо их именования, способ загрузки файлов Yarnrc также был изменен и упрощен. В частности:
Yarn больше не использует конфигурацию из ваших файлов
.npmrc; вместо этого мы читаем всю конфигурацию из файлов.yarnrc.yml, доступные настройки которых можно найти в нашей документации.Как упоминалось в предыдущем разделе, файлы yarnrc теперь называются
.yarnrc.yml, с расширением. Мы полностью прекратили чтение значений из обычных файлов.yarnrc.Все переменные среды, начинающиеся с
YARN_, автоматически используются для переопределения соответствующих параметров конфигурации. Например, добавлениеYARN_NPM_REGISTRY_SERVERв вашу среду изменит значениеnpmRegistryServer.
Проверьте наши end-to-end тесты
Теперь мы ежедневно проводим end-to-end тесты с различными популярными инструментами JavaScript, чтобы убедиться, что мы не вносим регрессии — или чтобы получать уведомления, когда эти инструменты их вносят.
Просмотр исходного кода этих тестов — отличный способ проверить, нужно ли устанавливать какие-то особые значения конфигурации при использовании определённой цепочки инструментов.
Не используйте bundleDependencies
bundleDependencies (или bundledDependencies) — артефакт прошлого, который позволял определять набор пакетов, которые сохранялись в архиве пакета как есть, node_modules и всё остальное. Эта функция имеет много проблем:
- Она использует
node_modules, что не позволяет легко использовать разные стратегии установки, такие как Plug'n'Play. - Она кодирует инкапсуляцию внутри пакета, что прямо противоположно тому, к чему мы стремимся.
- Она мешает инкапсуляции других пакетов.
- И так далее.
Как их заменить? Есть несколько способов:
Если вам нужно внести изменения в пакет, просто создайте его вилку или сошлитесь на него через
file:(это вполне допустимо даже для транзитивных зависимостей). Протоколыportal:иpatch:также являются вариантами, хотя они будут работать только для потребителей Yarn.Если вам нужно предоставить пакет вашим клиентам как автономный (без зависимостей), соберете его самостоятельно с помощью Webpack, Rollup или аналогичных инструментов.
При необходимости: включите плагин node-modules
Несмотря на все наши усилия, некоторые инструменты вообще не работают в средах Plug'n'Play, и у нас нет ресурсов для их обновления самостоятельно. В нашем списке есть только два известных: Flow и React Native.
В таком радикальном случае вы можете включить встроенный плагин node-modules, добавив следующее в ваш локальный файл .yarnrc.yml перед запуском нового yarn install.
nodeLinker: node-modulesЭто заставит Yarn установить проект так же, как Yarn 1, копируя пакеты в различные папки node_modules.
Дополнительная информация о параметре nodeLinker.
Замените nohoist на nmHoistingLimits
Параметр nohoist из Yarn 1 был разработан специально для React Native (чтобы помочь ему работать с рабочими пространствами), но его работа (через шаблоны glob) вызывала много ошибок и путаницы, никто не был уверен, какие шаблоны нужно устанавливать. В результате мы упростили эту функцию, чтобы поддерживать только три определенных шаблона.
Если вы использовали nohoist, мы рекомендуем удалить его из вашей конфигурации манифеста и вместо этого задать nmHoistingLimits в файле yarnrc:
nmHoistingLimits: workspacesКоманды командной строки
Переименованные
Yarn Classic (1.x) |
Yarn (2.x) |
Примечания |
|---|---|---|
yarn audit |
yarn npm audit |
|
yarn create |
yarn dlx create-<name> |
yarn create по-прежнему работает, но рекомендуется использовать yarn dlx
|
yarn global |
yarn dlx |
Посвящённый раздел |
yarn info |
yarn npm info |
|
yarn login |
yarn npm login |
|
yarn logout |
yarn npm logout |
|
yarn outdated |
yarn upgrade-interactive |
Подробнее на GitHub |
yarn publish |
yarn npm publish |
|
yarn tag |
yarn npm tag |
|
yarn upgrade |
yarn up |
Теперь будет обновлять пакеты во всех рабочих пространствах |
yarn install --production |
yarn workspaces focus --all --production |
Требует плагин workspace-tools |
yarn install --verbose |
YARN_ENABLE_INLINE_BUILDS=true yarn install |
Удалено из ядра
Yarn Classic (1.x) |
Примечания |
|---|---|
yarn check |
Целостность кэша теперь проверяется при обычных установках; Подробнее на GitHub |
yarn import |
Сначала импортировать в Classic, затем мигрировать в 2.x |
yarn licenses |
Идеальный случай использования плагинов; Подробнее на GitHub |
yarn versions |
Используйте yarn --version и node -p process.versions
|
Ещё не реализовано
Эти функции просто ещё не реализованы. Приветствуется помощь!
Yarn Classic (1.x) |
Примечания |
|---|---|
yarn list |
yarn why может предоставить некоторую информацию в это время |
yarn owner |
В конечном итоге будет доступно как yarn npm owner
|
yarn team |
В конечном итоге будет доступно как yarn npm team
|
Устранение неполадок
Cannot find module [...]
Интересно, что эта ошибка часто не исходит от Yarn. На самом деле, увидеть это сообщение при работе с проектами Yarn 2 должно быть крайне редко и, как правило, указывает на то, что в вашей настройке что-то не так.
Эта ошибка появляется, когда Node исполняется без соответствующих переменных окружения. В таком случае, базовое приложение не сможет получить доступ к зависимостям, и Node выдаст это сообщение. Чтобы исправить это, убедитесь, что скрипт вызывается через yarn node [...] (вместо node [...]) при запуске из командной строки.
A package is trying to access another package [...]
Полное сообщение: Пакет пытается получить доступ к другому пакету, не указанному как зависимость первого.
Некоторые пакеты по той или иной причине некорректно указывают свои фактические зависимости. Теперь, когда мы полностью перешли на Plug'n'Play и применяем ограничения между различными ветвями дерева зависимостей, этот тип проблем начнёт проявляться сильнее, чем раньше.
Долгосрочное решение — отправить исправление с запросом на изменение (pull request) в исходный репозиторий, чтобы добавить недостающую зависимость к списку пакетов. Учитывая, что это иногда может занять некоторое время до слияния, у нас также есть более краткосрочное решение: создать .yarnrc.yml в вашем проекте, затем использовать настройку packageExtensions, чтобы добавить недостающую зависимость к соответствующим пакетам. После этого выполните yarn install для применения ваших изменений, и вуаля!
packageExtensions:
"debug@*":
peerDependenciesMeta:
"supports-color":
optional: trueЕсли вы также откроете PR в исходном репозитории, вы также сможете внести свой пакет расширения в наш плагин совместимости, помогая всему экосистеме двигаться вперёд.
© 2016–present Yarn Contributors
Licensed under the BSD License.
https://v3.yarnpkg.com/getting-started/migration