为什么一个npm模块的依赖总能安装到nested node_modules?

Why can an NPM module's dependency be always installed to nested node_modules?

如您所知,NPM v3 试图使依赖树尽可能平坦。以前我认为它嵌套安装依赖项只是为了解决冲突,以防同一模块有多个版本。

但是,我注意到模块 protractor 有一些奇怪的地方。它有一个依赖项 webdriver-manager,它始终嵌套安装到 node_modules/protractor/node_modules。您可以通过 运行 npm install protractor 在一个空文件夹中轻松复制它。

为什么会这样?

这是一个很好的问题,当前的行为是意料之中的。 npmV3 确实以扁平结构安装依赖项 Protractor 也以相同的方式安装

当 Protractor 与 npmV3

一起安装时

当 Protractor 与 npmV2.*

一起安装时

除了 webdriver-manager 仍处于嵌套结构之外,所有模块都安装在扁平结构中。这是因为依赖冲突。

As per official documentation

Your dependencies will now be installed maximally flat. Insofar as is possible, all of your dependencies, and their dependencies, and THEIR dependencies will be installed in your project's node_modules folder with no nesting. You'll only see modules nested underneath one another when two (or more) modules have conflicting dependencies.

Now, let's say we want to require another module, C. C requires B, but at another version than A.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.

webdriver-manager package.json 列出了依赖项 "minimist": "^1.2.0",,这与其他软件包的要求冲突,例如需要以下依赖项列表的 optimist

  ├─ optimist@0.6.1
   │  ├─ wordwrap@0.0.3
   │  └─ minimist@0.0.10

因此,由于依赖冲突,webdriver-manager 安装在 protractor node_modules

为完整的依赖关系树和所有依赖关系之间的冲突做一个npm-remote-ls protractor