Использование 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 в проекте и символически связать его с /node_modules/new-refactored-package/ prior-existing-project. Из readme Лерны:

Загрузите пакеты в текущем репозитории Lerna. Устанавливает все их зависимости и связывает любые перекрестные зависимости.

При запуске эта команда:

  • npm устанавливает все внешние зависимости каждого пакета.
  • Свяжите вместе все пакеты Lerna, которые зависят друг от друга.
  • npm предварительно опубликовать все загруженные пакеты.

Однако когда я его запускаю, lerna пытается вместо этого npm install new-refactored-package:

npm ERR! Реестр 404 вернул 404 для GET на https://registry.npmjs.org/new-refactored-package < / а>

Я не понимаю? Должен ли я сначала опубликовать зависимые пакеты в npm?


person NiloCK    schedule 12.06.2017    source источник
comment
У меня такая же проблема! Документация вводит в заблуждение неопубликованные пакеты и ссылки. Я надеюсь, что здесь кто-нибудь сможет нам помочь.   -  person İbrahim Duran    schedule 14.06.2017


Ответы (4)


Требования

Чтобы 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 installed (или yarned), как обычно.
  • Теги dist, такие как latest, не соответствуют диапазонам semver.
  • Циклические зависимости приводят к циклическим символическим ссылкам, которые могут повлиять на ваш редактор / IDE.

Решение

Если вы хотите сопоставить любую доступную версию, рекомендуется установить версию "*". Это будет соответствовать любой версии и, следовательно, всегда будет использовать локальную версию, учитывая, что локальный пакет имеет указанное поле version.

{ 
  "dependencies": { 
    "new-refactored-package" : "*"
  }
}

alpha, rc or beta

Даже * не будет не соответствовать версиям, которые помечены как предварительные, поэтому, если вы дадите своему локальному пакету версию вроде 0.0.1-alpha.0 или 1.0.0-rc.3, он также не будет локально привязан к символической ссылке.

private: true

Хотя это не влияет на lerna bootstrap, стоит упомянуть, что пакеты, которые вы не хотите публиковать, всегда должны иметь private: true;. Это гарантирует, что lerna publish не опубликует его.

person oBusk    schedule 03.03.2019
comment
Я не понимаю, почему npm i [email protected] выдает мне эту ошибку, тогда как добавление ее вручную в package.json работает. - person Eric Burel; 26.02.2020
comment
@EricBurel Вы не можете установить локальный пакет с npm. Добавление его в package.json и последующий запуск lerna bootstrap может работать, если пакет доступен локально. Но npm не поддерживает локальные пакеты и не пользуется функциями lernas. Чтобы добавить пакеты, которые являются либо удаленными (опубликованные пакеты), либо локальными (в рабочем пространстве lerna), вы можете использовать lerna add [email protected] packages/app-to-install-in github.com/lerna/lerna/tree/master/commands/add - person oBusk; 27.02.2020
comment
@oBusk Означает ли это, что, как только я добавлю локальный пакет в качестве зависимости, я больше не смогу запускать npm install или npm uninstall <some other dependency>, так как он потерпит неудачу с npm ERR! 404 Not Found - GET https://registry.npmjs.org/<My-Lerna Local Dependency> - Not found - person Chandu; 11.06.2020
comment
@oBusk Похоже, что запуск npm uninstall в репо вызовет проблемы согласно github.com/lerna/ lerna / issues / 1229 :( - person Chandu; 11.06.2020

lerna bootstrap будет создавать символические ссылки на пакеты вместо установки, если они доступны.

В вашем случае я думаю, что lerna не может найти правильный 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
}
person kp_ping    schedule 20.07.2017
comment
Важны ли закрытый ключ и ключ версии? - person Larry Maccherone; 30.08.2018
comment
Версия требуется в зависимости (a_pkg), чтобы lerna могла гарантировать правильную версию. Зависимому (b_pkg) технически не требуется версия для работы начальной загрузки в этом сценарии. private: true влияет в первую очередь на lerna publish, чтобы не пытаться опубликовать пакет в NPM. Для работы начальной загрузки это не требуется. - person oBusk; 02.03.2019

lerna bootstrap проверит версию пакета, указанную вами в package.json или package-lock.json.

Поскольку вы не опубликовали свою работу, я бы попробовал использовать --force-local в команде bootstrap.

lerna bootstrap --force-local

person kitimenpolku    schedule 30.12.2019

Имя пакета в package.json должно совпадать с именем папки в папке / packages.

(По сути, то, что сказал @kp_ping)

person Jkarttunen    schedule 20.07.2018
comment
Папка может не совпадать с именем пакета. Зависимость должна иметь правильное имя и version, который может быть сопоставлен. - person oBusk; 02.03.2019