Is there an existing issue for this?
This issue exists in the latest npm version
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
- Install npm 10
- Install typedoc globally
npm i -g typedoc
- Install a typedoc theme globally
npm i -g typedoc-material-theme
- 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
- 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.
Is there an existing issue for this?
This issue exists in the latest npm version
Current Behavior
When installing a package globally, its peer dependencies are also always installed in its own
node_modulesdirectory 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
npmbehaves 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:
node_modulesdirectoryObviously, 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/typedocTo 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/typedocdirectory, rerun the command and everything went fine.Which is to be expected: the theme eventually requires
typedocwhich 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
Workarounds:
node_modules/typedocdirectory which may be challenging in a build system where we don't necessarily control where global packages are locatednpmrespect 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--legacy-peer-depsflag which is the best solution we found - it is simple and it works :partySteps To Reproduce
npm i -g typedocnpm i -g typedoc-material-themenode_modulesdirectory: you'll findtypedocinstalled under both the globalnode_modulesdirectory and undernode_modules/typedoc-material-theme/node_modulesEnvironment