How does NPM handle version conflicts ?
Consider a case where we have installed a module say A. Now we want to install another module called B and B depends on A but the problem is the version of A which is required by module B is different from the version of A installed at first. So how npm will handle this situation where our application depends on two different versions of module A. This is where version conflicts arise. The problem can be represented as follows.
In the above image, we can see that module B is dependent on version 2 of module A but the application already has module A with version 1 in its root.
Let’s understand this step by step taking the following cases:
Case 1: Both modules A and B does not have any dependency.
In this case, npm would simply add the modules as root dependency under node_modules. The dependency tree can be represented as:
Case 2: Module A has no dependency and module B depends on the same version of A.
In this case, the structure will remain the same as it was earlier. NPM would not install module A of the same version again as a dependency of B. Therefore, module A will only be bundled once. The dependency tree will be the same as it was in the previous case.
Case 3: Module A has no dependency and module B depends on the different version of A.
Npm installs dependencies in the order they are listed in the package.json file. So, it will encounter module A (version 1) first and install it as root dependency under node_modules. Now when npm is installing module B it checks whether the dependencies of module B are already installed as root dependencies or not. If they are already installed under node_modules npm would skip installing those dependencies. But in this case, a different version of module A is required for module B and the first version of A already exists as root dependency so npm would install module A (version 2) as a dependency of module B that means module B will have its own copy of node_modules under which the second version of A will be listed. In the output, both versions of module A will exist. The dependency tree can be represented as follows:
Case 4: Module A has no dependency and module B and C both depend on version 2 of module A.
Now in this case npm will first install module A (version 1) as the root dependency under node_modules. Module B and C will have their own copies of node_modules under which module A (version 2) will be listed. The thing to be noticed is that in the output module A (version 2) will be bundled twice because it is present as a dependency of B and C separately. Due to this, the output bundle has to include multiple copies of the same version of the same module. The dependency tree will look like this:
This is how npm handles version conflicts by making separate copies of node_modules for each dependency.