Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

As you know, NPM v3 tries to keep the dependency tree as flat as possible. Previously I thought it installs dependencies as nested only to solve conflicts in case there is more than one version of the same module.

However, I've noticed something strange about the module protractor. It has a dependency, webdriver-manager, which is always installed as nested, to node_modules/protractor/node_modules. You can easily reproduce this by running npm install protractor in an empty folder.

Why does this happen?

like image 558
thorn0 Avatar asked Oct 09 '16 22:10

thorn0


People also ask

Does npm install make node_modules?

js project, npm automatically creates the node_modules folder to store the modules needed for your project and the package-lock. json file that you examined earlier. The node_modules folder contains every installed dependency for your project.

Is it mandatory to commit the node_modules folder in your application?

Not committing node_modules implies you need to list all your modules in the package. json (and package-lock. json ) as a mandatory step. This is great because you might not have the diligence to do so, and some of the npm operations might break if you don't.

Do I need to install node modules every time?

We do not need to install a module every time when installed globally. It takes less memory as only one copy is installed. We can make . js scripts and run them anywhere without having a node_modules folder in the same directory when packages are installed globally.

What installs node_modules?

"npm install" installs all dependencies in node_modules directory, instead of having them nested.


1 Answers

Thats a great question and the current behavior is expected. npmV3 indeed installs dependencies in flat structure and Protractor is also installed the same way

When Protractor is installed with npmV3

enter image description here

When Protractor is installed with npmV2.*

enter image description here

All modules are installed in Flat Structure except that still webdriver-manager is still in nested structure. And this is because of conflicting dependencies.

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 lists dependencies "minimist": "^1.2.0",, which is in conflict requirements of other packages like optimist which needs the below dependency list

  ├─ [email protected]
   │  ├─ [email protected]
   │  └─ [email protected]

Hence due to conflicting dependencies, webdriver-manager is installed inside protractor node_modules

Do a npm-remote-ls protractor for complete dependency tree and conflicts across all dependencies

like image 96
AdityaReddy Avatar answered Sep 28 '22 07:09

AdityaReddy