Javascript NPM:在不同版本中多次下载同一个库

Javascript NPM:在不同版本中多次下载同一个库,javascript,angularjs,npm,jspm,Javascript,Angularjs,Npm,Jspm,我正在使用coffeescript开发Play Framework 2.4和AngularJs 1.5.8。 我正在分析使用npm是否方便。 我们正在使用几个库,其中许多库都有自己的依赖项。 所以,我不知道,如果两个不同的库具有相同的依赖关系,但版本不同,会发生什么? 这会引起问题吗?将在node_modules目录中下载哪个版本? 是否可以只使用npm使用同一个库的两个版本,或者我需要类似jspm的东西? 提前感谢。根据我的经验,NPM通常会用旧的软件包替换最新版本的软件包。因此,我认为如果您

我正在使用coffeescript开发Play Framework 2.4和AngularJs 1.5.8。 我正在分析使用npm是否方便。 我们正在使用几个库,其中许多库都有自己的依赖项。 所以,我不知道,如果两个不同的库具有相同的依赖关系,但版本不同,会发生什么? 这会引起问题吗?将在node_modules目录中下载哪个版本? 是否可以只使用npm使用同一个库的两个版本,或者我需要类似jspm的东西?
提前感谢。

根据我的经验,NPM通常会用旧的软件包替换最新版本的软件包。因此,我认为如果您使用NPM,则不可能存储同一软件包的两个不同版本。

NPM用于指定版本范围。默认情况下,当您运行
npm安装--save foo
时,它会下载
foo
包的最新版本,并将其编号存储在
package.json
依赖项中,以插入符号(^)开头。插入符号表示“兼容”,通常指具有相同主版本(第一个数字)的任何内容

当npm解析嵌套依赖项时,它会检查依赖项的版本字符串是否可以用单个版本解析。如果是,它会将该版本安装在顶级
节点\u模块
目录中。否则,它会在嵌套的
节点\u模块
目录中为每个模块安装一个版本


换句话说,它会自动处理这个问题,前提是发布者遵循语义版本控制约定,并且不会在次要版本或错误修复版本中包含破坏性更改。这是由社区强制执行的,因为不遵守上述约定是让人们不想使用你的东西的好办法。

NPM从一开始就被设计用来处理多个版本的依赖关系。它通过使所有NPM模块都有自己的node_modules目录来实现这一点,。这确实会导致模块膨胀,因此NPM后来被制作成智能地展平节点\ U模块目录(如果可能的话)

但现在,让我们先忘掉NPM和node_模块目录扁平化,想想如何可能有两个版本的相同依赖关系

假设我们有两个名为
X
Y
的模块,都需要一个名为
Z
的模块,问题是
X
需要的版本1和
Y
需要的版本2。NPM将创建一个类似->

node_modules X nodule_modules Z ver 1 Y nodule_modules Z ver 2 节点单元 X 结节模 Z版本1 Y 结节模 Z版本2 由于node搜索node_modules目录的方式,X始终会找到Z的正确版本,Y也是如此。这是因为node将首先检查当前目录中是否有node_modules,如果不存在,它将遍历目录树,直到找到名为Z的模块

现在回到扁平部分

如果X&Y现在都使用Z版本2。目录结构类似于

node_modules X Y Z ver 2 节点单元 X Y Z版本2 如您所见,X现在将找到zver2,Y也将找到zver2。 这是对节点如何进行模块解析的简要说明

希望对你有帮助


另外,正如@sripberger所指出的,知道保留和合并什么是由语义版本控制决定的。

NPM是为多种不同的依赖而设计的,。。NPM只会在满足semver要求的情况下取代DEPANCE。而且完全可以运行两个版本的NPM模块。IOW:大多数semver的只能在同一主要版本中升级。谢谢Keith!那么,node_modules目录呢?当我打开它时,会有两个同名文件夹还是npm重命名了它们?谢谢大家!@我会发布一个简短的解释。谢谢你的解释!这对我很有帮助。你们知道在这种情况下,是否有可能向节点表明我想成为谁来决定我想保存哪种版本的依赖关系?在你们的例子中,我想决定我要保存的Z的哪个版本,而那个节点只注意到发生了一个错误。如果这是你们的意思,可以忽略semver,基本上不允许NPM决定,。。只需复制所需的node_模块和版本。。我这样做的方式是创建一个临时目录,NPM将我想要的版本安装到这个目录中,然后将模块复制到当前的node_modules目录中。基本上忽略任何semver,您基本上不会在安装这些semver的目录中使用NPM。。你的手动控制依赖项。是的!这就是我想要的。所以,我将在我的项目中使用npm。谢谢