Две версии одного и того же пакета npm в приложении Node
Я работаю над инструментом CLI в NodeJS, который использует другой пакет NodeJs, который мы разрабатываем, который является SDK.
Дело в том, что мы только что опубликовали версию V2 этого SDK, и мы хотим предложить пользователю CLI устаревший режим, поэтому они могут использовать либо первую, либо вторую версию нашего SDK, например:
$ cli do-stuff
#execute sdk v2
или
$ LEGACY_MODE='on' cli do-stuff
#execute sdk v1
Моя проблема в том, что я не нашел никакого чистого способа использовать две версии одной и той же зависимости в моем CLI.
Я попытался использовать пакет npm-install-version. Он хорошо работает в моей локальной среде, но после публикации моего cli и выполнения npm install -g my-cli
он больше не работает, потому что он создает папку node_modules в текущей папке вместо папки /usr/local/lib/node_modules/my-cli
.
Я также пробовал multidep, и у меня есть одна и та же проблема.
На данный момент мой пакет .json вообще не содержит моего sdk, но я хотел бы иметь что-то вроде:
"dependencies": {
"my-sdk": "2.0.0"
"my-sdk-legacy": "1.0.0"
}
или
"dependencies": {
"my-sdk": ["2.0.0", "1.0.0"]
}
Я еще ничего не нашел. Я думаю о публикации первой версии моего пакета sdk с другим именем, например "my-sdk-legacy", но я хотел бы избежать этого, если это возможно.
Любое решение для этого?
Ответы
Ответ 1
Так что на самом деле это довольно распространенный сценарий, который рассматривался несколько раз.
Существует закрытая проблема для npm и открытая проблема для менеджеров пакетов пряжи.
Первое решение было предложено автором NPM в этом комментарии GH:
Опубликуйте отдельный пакет под другим именем. Это потребует определенной версии внутри.
{ "name": "express3",
"version": "1.0.0",
"description":"Express version 3",
"dependencies": { "express":"3" } }
// index.js
module.exports = require('express')
В вашем случае вы опубликуете my-sdk-v1
и my-sdk-v2
. И теперь вы можете легко установить 2 версии пакета в одном проекте, не сталкиваясь с конфликтами.
const mySDKLegacy = require('my-sdk-v1');
const mySDKModern = require('my-sdk-v2');
Второй способ, по большей части аналогичный предложенной, - использовать git url:
{
"my-sdk-v1": "git://github.com/user/my-sdk#1.0.0",
"my-sdk-v2": "git://github.com/user/my-sdk#2.0.0"
}
В отличие от пакета npm, вы можете выбрать любое имя! Источником правды является git url.
Позже выскочила npm-install-version
. Buuut, как вы уже доказали, его использование немного ограничено. Так как он порождает дочерний процесс для выполнения некоторых команд и записи в каталоги tmp. Не самый надежный способ для CLI.
Подводя итог: у вас остались варианты 1 и 2. Я бы остановился на первом, поскольку имя и теги репозитория github могут измениться.
Второй вариант с git url лучше, если вы хотите изменить версию, чтобы она зависела чаще. Представьте, что вы хотите опубликовать исправление безопасности для my-sdk-v1 legacy. Будет легче ссылаться на URL-адрес git, затем снова и снова публиковать my-sdk-v1.1
в npm.
Ответ 2
Таким образом, чтобы просто добавить к текущим решениям, вы также можете предоставить такие пакеты:
yarn add [email protected]:my-sdk
или в package.json
{
...
"my-sdk-newest": "npm:my-sdk",
"my-sdk": "1.0.0"
...
}
если вы заботитесь только о конкретной устаревшей версии и новейшей.
Ответ 3
Исходя из моего ответа на аналогичный вопрос:
Начиная с npm v6.9.0, npm теперь поддерживает псевдонимы пакетов. Он реализует тот же синтаксис, который использует Yarn:
npm install [email protected]:[email protected]
npm install my-sdk
Это добавляет следующее в package.json
:
"dependencies": {
"my-sdk-legacy": "npm:[email protected]^1.0.0",
"my-sdk": "2.0.0"
}
Мне кажется, это самое элегантное из доступных решений, которое совместимо с решением Yarn, предложенным @Aivus.