npm fails to install packed local dependencies with packed local dependencies

cli
help-wanted
priority:low
triaged

(Justin Lovinger) #1

What I Wanted to Do

npm install --save ./lib/A-1.0.0.tgz

What Happened Instead

ENOENT: no such file or directory, stat ‘[PATH_TO_MODULE]\lib\A-1.0.0.tgz\lib\B-1.0.0.tgz’

Reproduction Steps

  1. Create a module (B).
  2. npm pack B
  3. Create a module (A)
  4. Copy B-1.0.0.tgz to ./lib/B-1.0.0.tgz
  5. npm install --save ./lib/B-1.0.0.tgz in module A
  6. npm pack A
  7. Try to install A-1.0.0.tgz

Details

npm appears to treat the packed .tgz file as if it is a folder, thereby failing to find its local dependencies.

Platform Info

$ npm --versions
{ normalize: '1.0.0',
  npm: '6.1.0',
  ares: '1.13.0',
  cldr: '32.0',
  http_parser: '2.7.0',
  icu: '60.1',
  modules: '59',
  nghttp2: '1.25.0',
  node: '9.3.0',
  openssl: '1.0.2n',
  tz: '2017c',
  unicode: '10.0',
  uv: '1.18.0',
  v8: '6.2.414.46-node.15',
  zlib: '1.2.11' }

$ node -p process.platform
win32

(Lars Willighagen) #2

This seems relevant:

Takeaway: the PR I made in the other issue could work, but probably not if you move the tarball, since the relative paths of local dependencies would be wrong. Some possible solutions:

  1. Use bundleDependencies/bundledDependencies when possible
  2. Use absolute paths
  3. Don’t move the tarball (or pack in lib/a, referencing ../b)

I’m on mobile, so sorry for any typos, and I’ll check if bundledDependencies really works for this (it should) later. I might have checked for that already, but I don’t recall right now.


(Justin Lovinger) #3

bundledDependencies appears to work, but is really a work-around, not a fix.

Using absolute paths or not moving the tarball is not a satisfactory solution, as it removes the portability of the tarball and module.

Ultimately, npm should be able to install the dependency that is contained within the tarball, instead of erroneously treating it like a folder.


(Lars Willighagen) #4

The dependency isn’t contained within the tarball normally, that’s what bundledDependencies does. Without that, the dependency is just a relative file path. Even when npm treats A@1.0.0 like a file and not a folder (which the PR fixes), npm resolves the dependency ./lib/B-1.0.0.tgz in ./lib to ./lib/lib/B-1.0.0.tgz, which is still incorrect. However, npm can’t track where your tarball was, or if and how its dependencies get moved.


(Justin Lovinger) #5

In my example, the dependency is contained within the tarball.

If the module (A) is not packed into a tarball, npm can properly install the nested dependency (B). npm resolves the dependency ./lib/B-1.0.0 as ./lib/A-1.0.0/lib/B-1.0.0, which properly contains the B package. It does not resolve the dependency as ./lib/lib/B-1.0.0.

This problem only occurs when A is packed into a tarball, and the error message implies that npm is trying to traverse the tarball like a folder.


(Justin Lovinger) #6

I looked a little closer at this issue

And it looks like that is unrelated to the issue I am reporting here. In the linked issue, the dependency is located outside of the module, which will not work if the module is moved, regardless of whether or not it is a tarball.

In my issue, the dependency is located within the module (and the tarball), and does work if the module is not packed into a tarball.

The issue reported here is specifically an issue with packed modules, and appears to occur because npm attempts to traverse the tarball like a folder.


(Lars Willighagen) #7

Oh, I missed that. Thanks for the clarification, and my apologies for my stubbornness.


(Justin Lovinger) #8

Now that the confusion has been resolved, I’m switching this back to the bugs category, from support, unless there is another reason why this would not be considered an issue.

Also, I am not sure if this should be re-triaged or how to go about that, given that the initial triage seemed to (I believe mistakenly) classify this issue as not-a-bug.

P.S. No problem @larsgw.