Skip to content

[BUG] Installing a package globally also installs its peerDependencies even if they are already available globally #7057

Description

@ericmorand

Is there an existing issue for this?

  • I have searched the existing issues

This issue exists in the latest npm version

  • I am using the latest npm

Current Behavior

When installing a package globally, its peer dependencies are also always installed in its own node_modules directory even when these peer dependencies are already installed globally.

Expected Behavior

I expect that the peer dependencies available globally are not installed globally twice when they are the same version, just like npm behaves when installing locally.

Having multiple versions of the same global dependency creates some issues with typedoc (probably among some other tools) where typedoc ends up installed twice:

  • globally
  • under each theme node_modules directory

Obviously, when executing the typedoc binary to build a documentation, the executed instance of typedoc is not the one that is required by the theme, leading to the infamous error:

$ typedoc src/lib.ts --out public --plugin typedoc-material-theme
[info] Loaded plugin typedoc-material-theme
[warning] TypeDoc has been loaded multiple times. This is commonly caused by plugins which have their own installation of TypeDoc. The loaded paths are:
        /home/ericmorand/.nvm/versions/node/v18.19.0/lib/node_modules/typedoc
        /home/ericmorand/.nvm/versions/node/v18.19.0/lib/node_modules/typedoc-material-theme/node_modules/typedoc

To confirm that there is no need to install "locally" peer dependencies that are already installed globally, I deleted the /home/ericmorand/.nvm/versions/node/v18.19.0/lib/node_modules/typedoc-material-theme/node_modules/typedoc directory, rerun the command and everything went fine.

Which is to be expected: the theme eventually requires typedoc which is then resolved to the package installed one level above the theme, as per the resolution rule of node:

https://nodejs.org/api/modules.html#loading-from-node_modules-folders

If the module identifier passed to require() is not a core module, and does not begin with '/', '../', or './', then Node.js starts at the directory of the current module, and adds /node_modules, and attempts to load the module from that location. Node.js will not append node_modules to a path already ending in node_modules.

If it is not found there, then it moves to the parent directory, and so on, until the root of the file system is reached.

Workarounds:

  • Removing the theme node_modules/typedoc directory which may be challenging in a build system where we don't necessarily control where global packages are located
  • Installing typedoc and the themes locally which makes npm respect the rule of not installing twice the same dependency - but it means all our projects need to be reworked because none of them include typedoc or its themes: our build system is responsible for the documentation building and it is where we enforce some common typedoc themes and settings for all our products, for consistency and convenience
  • Installing the theme using the --legacy-peer-deps flag which is the best solution we found - it is simple and it works :party

Steps To Reproduce

  1. Install npm 10
  2. Install typedoc globally npm i -g typedoc
  3. Install a typedoc theme globally npm i -g typedoc-material-theme
  4. Look into the global node_modules directory: you'll find typedoc installed under both the global node_modules directory and under node_modules/typedoc-material-theme/node_modules
  5. Also note how they are exactly the same version

Environment

  • npm: 10.2.4
  • Node.js: 18.19.0
  • OS Name: Ubuntu
  • npm config:
; "user" config from /home/ericmorand/.npmrc

//registry.npmjs.org/:_authToken = (protected) 

; node bin location = /home/ericmorand/.nvm/versions/node/v18.19.0/bin/node
; node version = v18.19.0
; npm local prefix = /home/ericmorand/Projects/twing
; npm version = 10.2.3
; cwd = /home/ericmorand/Projects/twing
; HOME = /home/ericmorand
; Run `npm config ls -l` to show all defaults.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions