NPM Indirect Dependency Version Issues

· 2 min read

Package.json contains dependencies and devDependencies, which are collectively referred to as direct dependencies. However, the packages we depend on may themselves depend on other packages. How are the versions of these indirect dependencies managed? And when our project directly depends on A 1.x while an indirect package depends on A 2.x, which version will ultimately be installed - 1.x or 2.x?

The Answer

Actually, both versions will coexist. The package.json records a dependency tree, and the storage structure under node_modules reflects this.

For example, a project depends on @types/react, while the dependency @types/react-router-dom indirectly depends on @types/react.

Note

The * here indicates any version, so the latest version will be installed during installation.

Executing yarn install

As shown above, the project actually installs two versions of @types/react. One version 16.8.25 is at the root of node_modules, while another version 16.9.17 is under @types/react-router-dom.

The Error

When there are two versions of @types/react, executing the build command results in an error:

Solution

Remove the direct dependency on @types/react, re-run the installation, and we’ll see a single 16.9.17 version at the root of node_modules, with no @types/react under @types/react-router-dom. Re-running the build command no longer produces errors.

Conclusion

  1. When our package has both direct and indirect dependencies on different versions of the same package, both versions will actually be installed
  2. When direct and indirect dependencies require the same version, the package will be placed at the root path. When multiple versions exist, each package will be placed under the path of the package that depends on it

Extension

Sometimes in projects, we need to understand how a package@version was introduced into the project. With layered dependencies, it’s not easy to directly check through lock files or node_modules. Fortunately, npm-cli provides query support:

 npm ls bignumber.js --package-lock-only

https://static.1991421.cn/2022/2022-09-18-122028.jpeg

As shown in the image, we can see that bignumber.js@9.0.0 was installed into the project as a direct dependency of mysql.

References