heuristics of project root discover re `.npmrc

What I Wanted to Do

Wanted to install packages in new project directory without a package.json though with an .npmrc. I was expecting packages to be installed into said directory.

What Happened Instead

The packages were installed into home directory, but not before npm created a package.json there where there had been none.

Reproduction Steps

Create a project directory. Create an .npmrc there. Add, say, a project level prefix definition. Install something.

Details

Npm should either treat a directory with .npmrc, lacking a package.json, as project root; or, it should query the user before installing package in a parent/HOME directory.

Platform Info

macos 10.14.5

$ npm --versions
{ bridges: '1.0.0',
  npm: '6.9.0',
  ares: '1.14.0',
  cldr: '33.1',
  http_parser: '2.8.0',
  icu: '62.1',
  modules: '64',
  napi: '3',
  nghttp2: '1.33.0',
  node: '10.10.0',
  openssl: '1.1.0i',
  tz: '2018e',
  unicode: '11.0',
  uv: '1.23.0',
  v8: '6.8.275.30-node.24',
  zlib: '1.2.11' }

I was not able to reproduce your problem. I get an error that package.json does not exist, and a package-lock.json created in the current folder.

npm commands can be run from deeper in a project hierarchy than in the root, but I think it is the package.json which defines the root. (I’ll try and find some relevant documentation.)

Have you got configuration in your .npmrc which would change the behaviour?

Found the project root description: https://docs.npmjs.com/files/folders#more-information

Starting at the $PWD, npm will walk up the folder tree checking for a folder that contains either a package.json file, or a node_modules folder. If such a thing is found, then that is treated as the effective “current directory” for the purpose of running npm commands. (This behavior is inspired by and similar to git’s .git-folder seeking logic when running git commands in a working dir.)

If no package root is found, then the current folder is used.

Moved to #support with expectation that behaviour matches documentation (pending information to the contrary!).

Apologies for not being clearer. This is the scenario I’m trying to describe:

  • Given a folder structure “/alpha/bravo/”
  • Given project structure A “/alpha/package.json”
  • Given potential project B with an .npmrc with path “/alpha/bravo/.npmrc”
  • And, given that said .npmrc has the following content per docs:
prefix = "/alpha/bravo/"

The expectation is that, when $PWD is “/alpha/bravo”, that npm i lodash would install lodash under “/alpha/bravo/node_modules/” irrespective of whether potential project B directory contains a package.json file.

Does that clarify things?

Nice description, thanks. I see what you were hoping would happen.

The project .npmrc file gets looked for in the project root, so I expect does not get consulted after npm finds a project root up the hierarchy: https://docs.npmjs.com/files/npmrc?#per-project-config-file

You could create a package.json file or node_modules folder in /alpha/bravo to get npm to do the “new project” installs locally?