Использование Lerna с неопубликованными пакетами
Я пытаюсь настроить мой монорепо с Лерной. План состоит в том, чтобы реорганизовать существующий проект, извлекая куски кода, которые должны быть их собственными пакетами. Я бегал lerna init
и мои текущие настройки выглядят так:
project/
packages/
new-refactored-package/
package.json
prior-existing-project/
package.json
{ "dependencies" : { "new-refactored-package" : "latest" } }
package.json
{
"devDependencies": {
"lerna": "^2.0.0-rc.5"
}
}
lerna.json
{
"lerna": "2.0.0-rc.5",
"packages": [
"packages/*"
],
"version": "0.0.0"
}
Я понимаю, что lerna bootstrap
на данный момент предполагается найти package1
в проекте и символическую ссылку на него prior-existing-project
"s /node_modules/new-refactored-package/
, Из readme Лерны:
Загрузите пакеты в текущем репозитории Lerna. Устанавливает все их зависимости и связывает любые перекрестные зависимости.
При запуске эта команда будет:
- npm устанавливает все внешние зависимости каждого пакета.
- Symlink объединяет все пакеты Lerna, которые являются зависимостями друг от друга.
- npm предварительно публикует все загруженные пакеты.
Однако, когда я запускаю его, Лерна пытается вместо npm install new-refactored-package
:
нпм ERR! 404 Реестр вернул 404 для GET на https://registry.npmjs.org/new-refactored-package
Я неправильно понимаю? Должен ли я сначала опубликовать зависимые пакеты в npm
?
5 ответов
Требования
За lerna
символическую ссылку на локальный пакет при запуске lerna bootstrap
местный пакет должен иметь name
а также version
это соответствует. Всякий раз, когда lerna
не может сопоставить зависимость с локальным пакетом, он попытается установить его из реестра.
Поэтому убедитесь, что пакет зависимостей имеет версию, которая может совпадать с версией semver в зависимой.
пример
{
name: "@my-name/dependency",
version: "1.2.0"
}
{
name: "@my-name/dependant",
dependencies: {
"@my-name/dependency": "<VERSION>"
}
}
@my-name/dependency
будет символом, когда VERSION
является 1.2.0
, ^1.0.0
, 1.X.X
, или же *
, Однако при использовании диапазонов, которые не соответствуют локальному пакету, как 1.0.0
или же ^0.0.0
, он попытается разрешить его в реестре npm и покажет ошибку как 404 Not Found - GET https://registry.npmjs.org/@my-name%2fdependency - Not found
,
latest
В фактическом сценарии, который объясняется в вопросе, фактическая проблема заключается в том, что версия указана как latest
и хотя легко думать, что latest
это общий термин для последней доступной версии, это на самом деле npm-dist-tag
который применяется по умолчанию для всех новых выпусков.
Если вы посмотрите на пакеты, как react
(нажмите версии), вы можете увидеть, что кроме latest
они также используют версии с тегами next
, canary
а также unstable
,
Ваш неопубликованный пакет не имеет каких-либо тегов, так как они применяются при публикации и т. Д. latest
не будет соответствовать, то есть lerna
будет пытаться разрешить его удаленно, с ошибкой 404
,
Это отмечено как одна из ошибок в примечаниях документации для bootstrap
команда.
- Если версия зависимости в пакете не удовлетворяется пакетом с тем же именем в репо, это будет
npm install
Эд (илиyarn
ред) вроде нормально.- Dist-теги, как
latest
, не удовлетворяют семи диапазонам.- Циркулярные зависимости приводят к появлению циклических символических ссылок, которые могут повлиять на ваш редактор /IDE.
Решение
Если вы хотите соответствовать любой доступной версии, рекомендуемый путь - установить версию на "*"
, Это будет соответствовать любой версии и, таким образом, всегда будет использовать локальную версию, учитывая, что локальный пакет имеет указанный version
поле.
{
"dependencies": {
"new-refactored-package" : "*"
}
}
alpha
,rc
или жеbeta
Четное
*
не будет соответствовать версиям, которые помечены как предварительные версии, поэтому, если вы предоставите вашему локальному пакету такую версию, как0.0.1-alpha.0
, или же1.0.0-rc.3
, это также не будет локально символически
private: true
Пока это не влияет lerna bootstrap
Стоит отметить, что пакеты, которые вы не хотите публиковать, всегда должны иметь private: true;
, Это обеспечит lerna publish
не публикует это.
lerna bootstrap
будут пакеты с символической ссылкой вместо установки, если они доступны.
В вашем случае, я думаю, что Лерна не может найти правильный version
или же name
пакета.
Вот что я сделал в своем проекте...
project
- packages/
- a_pkg
- package.json {
"name": "@scope/a_pkg",
"version": "0.0.1",
"private": true
/// opt out
}
- b_pkg
- package.json {
"name": "@scope/b_pkg",
"version": "0.0.1",
"private": true,
"dependencies": {
"@scope/a_pkg": "^0"
},
/// opt out
}
- package.json
- lerna.json {
"packages": [
"packages/*"
],
/// opt out
}
lerna bootstrap
проверит версию пакета, которую вы указали в package.json
или package-lock.json
.
Поскольку вы не опубликовали свою работу, я бы попробовал использовать --force-local
на bootstrap
команда.
lerna bootstrap --force-local
Попробуйте установить зависимости с помощью команды "lerna add <DEPENDENCY_NAME>" вместо добавления зависимостей вручную. Это автоматически добавит локальную версию (если доступна)
Имя пакета в package.json должно совпадать с именем папки в папке /packages.
(По сути, то, что сказал @kp_ping)