Использование 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)

Другие вопросы по тегам