npm3 如何决定安装平面还是嵌套?

How does npm3 decides to install flat vs. nested?

我的项目依赖angular2 beta.6,另一个项目依赖angular2 beta.0。

package.json 我的项目

"dependencies": {
    "angular2": "2.0.0-beta.6",
    "another-project": "0.0.1"
}

package.json 另一个项目

"dependencies": {
    "angular2": "2.0.0-beta.0",
}

当我 npm install 我的项目时,它安装 angular2 两次:

  1. node_modules/angular2 (beta.6)
  2. node_modules/another-project/angular2 (beta.0)

试图了解 npm3 如何决定嵌套 angular2 beta.0。是不是因为都叫angular2所以不能都在顶层?

Trying to understand how npm3 decides to nest angular2 beta.0. Is it because both are called angular2 and hence they can not both sit at the top level?

是的,这是正确的。节点代码 require 是一个按名称命名的模块,使用如下代码:

require('angular2');

Node 本身并不知道不同的版本,这是 npm 的工作,所以它只是首先使用 require 路径中匹配的任何模块,依赖于匹配的目录名称。

npm 通过在发生冲突时在每个模块的目录中安装特定版本来解决这个问题,以便 require 路径首先包含它。

对,就是因为beta.0。因为npm在全球范围内找到了另一个版本的angular2,所以会在本地安装。

npm3 只有在更高级别上没有其他版本的依赖项时才会安装全局依赖项。

这是我找到的一个小例子:

  • [node_modules]
    • dep A v1.0
    • dep B v1.0
      • dep A v1.0(使用root版本)
    • dep C v1.0
      • dep A v2.0(此版本与root版本不同,所以会嵌套安装)

npm v3 中引入了平面依赖项。可以在此处找到文档 https://docs.npmjs.com/how-npm-works/npm3.

从文档中回答您的问题

However, since B v1.0 is already a top-level dep, we cannot install B v2.0 as a top level dependency. npm v3 handles this by defaulting to npm v2 behavior and nesting the new, different, module B version dependency under the module that requires it -- in this case, module C.

所以顺序很重要。您首先安装的模块将依赖于顶层。后续模块将具有嵌套依赖项。

您可以 运行 npm dedupe 删除嵌套模块依赖项(如果它们存在于顶层)。