如何使用npm安装软件包的多个版本


100

由于https://github.com/npm/npm/issues/2943,npm将永远不支持对软件包进行别名并安装同一软件包的多个版本的功能。

github问题上发布的变通办法可能适用于纯JS模块,但是随着npm成为前端软件包管理的标准,软件包现在包括各种资产,例如CSS。

有没有解决办法来安装同一软件包的多个版本?

我想出的最好的主意是“克隆”一个程序包,并以稍微不同的名称发布它。

例如,如果你需要的多个版本jquery,你可以只包发布所谓jquery-alias1jquery-alias2jquery-alias3等,然后设置相应的版本你package.json

或者你可以根据自己的版本号,比如命名的包jquery-1.11.xjquery-2.1.x等等。

不过,这两种方法似乎都是草率的。有更好的吗?


可以轻松做到这一点的前端软件包管理不是​​标准。
laggingreflex 2014年

是的,凉亭似乎在这里是另一种选择。遗憾的是,似乎没有npm解决方案,因为要向大型团队引入另一个软件包管理系统可能很困难。特别是如果您已经设置了支持npm的基础结构(例如,私有的npm注册服务器)
标记

Answers:


102

npm v6.9.0开始, npm现在支持软件包别名。它实现了与Yarn相同的语法

npm install jquery2@npm:jquery@2
npm install jquery3@npm:jquery@3

这会将以下内容添加到package.json

"dependencies": {
   "jquery2": "npm:jquery@^2.2.4",
   "jquery3": "npm:jquery@^3.4.1"
}

也可以使用这种语法直接从GitHub安装。例如,如果您要安装软件包的npm注册表版本和GitHub分支foobar

npm install foobar
npm install foobar-fork@github:username/foobar

1
还支持包混叠
Greg K

嗨,我已经尝试过这些步骤来安装2软件包:“ react-native-track-player”:“ 1.1.4”和“ react-native-track-player”:“ 1.1.8”。它在iOS上运行良好,但在Android上显示“多次定义MusicManager $ 1”的错误。如何防止Android构建1.1.8?
EmBeCoRau

由于库中有些冲突,我需要在iOS上使用1.1.8,在Android上使用1.1.4
EmBeCoRau

没有为我工作,因为依赖项的别名与它要查找的内容不同,即它正在寻找eslint,但不知道它现在的名称是什么?eslint6
Crimbo

75

我想在这里发布信息给像我这样使用Yarn并降落在这里的任何人。它或多或少是NPM的直接替代品,支持即开即用的别名:

yarn add material-ui@latest
yarn add material-ui-next@npm:material-ui@next
then

import FlatButton from 'material-ui/FlatButton'; // v0.x
import Button from 'material-ui-next/Button'; // v1.x

(例如,贷方转到https://github.com/callemall/material-ui/issues/7195#issuecomment-314547601


17
谢谢。只是为了澄清通用公式是 <alternative-name>@npm:<package-name>@<version>
NikosKeyz

5

听起来“ JSPM”可能正是您要寻找的工具。JSPM建立在NPM之上,但允许您从多个来源(github,npm等)提取软件包。它使用前端的System.js通用模块加载器来加载模块,并“使用简单的版本管理将其下载到带有版本后缀的文件夹中”,这一点很容易理解。

jspm.io

使用jspm安装软件包时,可以将该软件包别名为一个特定的名称,以后可以require在模块中专门指定该名称。

$ jspm install jquery
... (status msgs) ...
ok   Installed jquery as github:components/jquery@^2.1.4 (2.1.4)

$ jspm install jqueryOne=jquery@1.11.3
... (status msgs) ...
ok   Installed jqueryOne as github:components/jquery@1.11.3 (1.11.3)

      github:components/jquery 1.11.3 2.1.4

然后在您的js中,您可以简单地require(jquery)和/或require(jqueryOne)根据需要进行操作,并允许您根据需要来回移动。

对于要使用其多个版本的任何软件包,这都是相同的。


2

由于npm的工作方式,很难做到干净整洁,所以我会避免尝试在生产中进行。

但是,对于集成测试和类似的用例,我创建了一个名为multidep的软件包,该软件包可让您安装同一软件包的多个版本,require如下所示:

var multidepPackages = require('multidep')('test/multidep.json');

var jquery1 = multidepRequire('jquery', '1.11.3');
var jquery2 = multidepRequire('jquery', '2.1.4');

0

也可以选择NPM安装版本(https://github.com/scott113341/npm-install-version)。它实际上完成了此处其他一些解决方案的工作(在技术上讲),但是使用起来非常简单。可预见的是,安装了版本号(NPM使用的标准@version命令参数)的模块可以安装在具有该名称的node_modules下的子文件夹中。您还可以控制每个模块的目标目录-这对于构建系统很有用。

GitHub Docs的使用代码片段:

const niv = require('npm-install-version');
const benchmark = require('./some-benchmark-function.js');

niv.install('csjs@1.0.0');
// installs csjs@1.0.0 to node_modules/csjs@1.0.0/

niv.install('csjs@1.0.1');
// installs csjs@1.0.1 to node_modules/csjs@1.0.1/

const csjs_old = niv.require('csjs@1.0.0');
const csjs_new = niv.require('csjs@1.0.1');
// require the old and new versions of csjs

benchmark([csjs_old, csjs_new], 'some-test-input');
// run our fake benchmark function on the old and new versions of csjs

0

install-npm-versionhttps://github.com/scott-lin/install-npm-version)是另一种选择。它可以在命令行上使用,也可以通过编程接口使用-用TypeScript编写的用于现代开发。

示例#1:安装到版本化(默认)目录

import inv = require('install-npm-version');

inv.Install('chalk@2.4.0');
// installs chalk@2.4.0 to node_modules/chalk@2.4.0/

inv.Install('chalk@2.4.1');
// installs chalk@2.4.1 to node_modules/chalk@2.4.1/

示例2:安装到自定义目录

import inv = require('install-npm-version');

inv.Install('chalk@2.4.0', { 'Destination': 'some/path/chalk' });
// installs chalk@2.4.0 to node_modules/some/path/chalk/

例3:以静默或嘈杂的标准输出进行安装

import inv = require('install-npm-version');

inv.Install('chalk@2.4.0', { 'Verbosity': 'Silent' });
inv.Install('chalk@2.4.0', { 'Verbosity': 'Debug' });

示例#4:覆盖现有安装

import inv = require('install-npm-version');

inv.Install('chalk@2.4.0', { 'Destination': 'mydir' });
// installs chalk@2.4.0 to node_modules/mydir/

inv.Install('chalk@2.4.1', { 'Destination': 'mydir' });
// does not install chalk@2.4.1 since node_modules/mydir/ already exists

inv.Install('chalk@2.4.1', { 'Destination': 'mydir', 'Overwrite': true });
// installs chalk@2.4.1 to node_modules/mydir/ by overwriting existing install

0

就我而言,我需要安装一个比全球安装的版本更旧的create-react-app版本,因为我上的课程要求使用该旧版本进行作业。

我创建了一个新文件夹,仅包含此旧版本,将其cd入其中,然后

npm init

设置完该shell package.json之后,我安装了所需的确切版本的create-react-app

npm install create-react-app@1.5.2

它使用旧版本的create-react-app创建了一个本地node_modules文件夹。

然后,我创建了一个简单的bash脚本(create-react-app.sh)作为此旧版本的快捷方式,并使用bash变量“ $ @”转发所有参数:

#!/bin/bash
{full-directory-path}/node_modules/create-react-app/index.js "$@"

最后,我使这个简单的bash脚本可执行

chmod u+x create-react-app.sh

因此,直接运行此bash脚本将执行旧版本的create-react-app:

./create-react-app.sh  --version
1.5.2
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.