npm pack hangs when using bundledDependencies with file links

TL;DR

When running npm pack with bundledDependencies, if those dependencies are file: based modules, then npm pack does not respect the .npmignore file in the file: based module directory.

Best-case this results in a bloated pack .tgz file with unexpected contents included. Worst-case (as in the example below) this results in a hang as npm pack tries to recurse infinitely into excluded files.

What I Wanted to Do

I have an awesome-library with a file structure like follows:

/awesome-library
    /package.json
    /package-lock.json
    /dist
        /out.js

I wanted to add awesome examples to awesome-library but have them be a bit more self-contained. Something a user could easily copy out of GitHub and update without making major changes.

For example with this structure a user just needs to change a dependency from file:…/… to awesome-library@version They do not need to modify source to change require(’…/…/’) statements to require(‘awesome-library’) statements. It makes the example source look more like real source. It also makes front-end examples much easier to understand as the folder structure for examples matches how it looks when consumed, ie import './node_modules/awesome-library/dist/out.js';

To do this I added example/playground as follows:

/awesome-library
    /package.json
    /package-lock.json
    /dist
        /out.js
    /example
        /playground
             /package.json
             /package-lock.json

Then in example/playground/package.json I run npm install ../../ and it adds dependency:

"awesome-library": "file:../.."

So far everything seems great! A user contributing new dev can sync the root repo, build, and then if they want to try an example (they are BIG with lots of dependencies) they can go into the example and run npm install to get all the dependencies

Now I want to make it so you can easily package up the example in a standalone unit. Handy for publishing to docs / github-pages or asking for reproductions for issues to send in.

So in example/playground/package.json I add:

"bundledDependencies": ["awesome-library"]

Now if I run npm pack I expect a tgz file to get created that contains a node_modules folder with the awesome-library dependency with files from .npmignore filtered out. This is what my .npmignore looks like:

**/*
!dist/*.js

What Happened Instead

Instead when I run npm pack the tool hangs indefinitely. My guess is that it gets stuck crawling into the linked file:…/… path which contains the example/playground folder which contains node_modules with awesome-library which contains example/playground which contains node_modules with awesome-library, ad infinitum…

I think a sane way to break the cycle is to respect the .npmignore file. That would be great for the size of bundled dependencies pointing to other file: based dependencies in a not recursive case as well.

For example when I make the example a sibling instead:

/awesome-library/package.json
/playground/package.json

and playground/package.json looks like:

"dependencies": "../awesome-library",
"bundledDependencies": ["awesome-library"]

Then the bundled output is huge because the .npmignore in awesome-library was ignored when running npm pack.

Reproduction Steps

See above. There was a lot of premise involved that is also repro steps.

Details

I think both the recursive file: bundledDependencies hang in npm pack and the bloated file: bundledDependencies issue in npm pack can be resolved by having npm pack respect .npmignore files for file: based modules when running.

Platform Info

$ npm --versions
{ 'vireo-playground': '0.0.1',
  npm: '6.5.0',
  ares: '1.14.0',
  cldr: '33.1',
  http_parser: '2.8.0',
  icu: '62.1',
  modules: '64',
  napi: '3',
  nghttp2: '1.34.0',
  node: '10.14.1',
  openssl: '1.1.0j',
  tz: '2018e',
  unicode: '11.0',
  uv: '1.23.2',
  v8: '6.8.275.32-node.36',
  zlib: '1.2.11' }
$ node -p process.platform
win32

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.