npm Community Forum (Archive)

The npm community forum has been discontinued.

To discuss usage of npm, visit the GitHub Support Community.

npm install --no-optional not actually filtering optionals in CLI 6.0.1 or 6.1.0

Note: I would love to help fix this but I have no contributing experience with npm yet so I could probably use pointers/advice on where to begin looking in the GitHub npm/npm repo.

What I Wanted to Do

mkdir test
cd test
npm init
npm install --no-optional log4js

Log4JS is just a convenient example because right now it has an optional dependency to loggly which happens to have security vulnerabilities in it, so success/failure is shown instantly with the “found 6 vulnerabilities” prompt.

The dependency tree tree in package.json should then look like:


This should all be linearizable into just 17 packages installed at the top level in package.json. (I mean some of those might be optional dependencies of non-optional dependencies so hypothetically this number could be lower, but it shouldn’t be any higher.

What Happened Instead

I get:

+ log4js@2.9.0
added 52 packages from 58 contributors and audited 438 packages in 6.274s
found 6 vulnerabilities (1 low, 5 moderate)
  run `npm audit fix` to fix them, or `npm audit` for details

Note that the package count is way higher than it should be on account of the log4js package.json including
several heavier optional dependencies as logging backends: optionalDependencies contains amqplib, axios, hipchat-notifier, loggly, mailgun-js, nodemailer, redis, and slack-node.

Reproduction Steps

Create folder, run npm install --no-optional log4js and see how many packages it installs.


Well I started out with:

{ npm: '6.0.1',
  ares: '1.14.0',
  cldr: '33.0',
  http_parser: '2.8.0',
  icu: '61.1',
  modules: '64',
  napi: '3',
  nghttp2: '1.29.0',
  node: '10.1.0',
  openssl: '1.1.0h',
  tz: '2018c',
  unicode: '10.0',
  uv: '1.20.2',
  v8: '6.6.346.27-node.6',
  zlib: '1.2.11' }

During the course of filing this I updated npm to 6.1.0 but everything else has stayed the same.

This also applies on my Windows box where the versions are

{ npm: '6.1.0',
  ares: '1.10.1-DEV',
  cldr: '31.0.1',
  http_parser: '2.7.0',
  icu: '59.1',
  modules: '57',
  nghttp2: '1.25.0',
  node: '8.9.4',
  openssl: '1.0.2n',
  tz: '2017b',
  unicode: '9.0',
  uv: '1.15.0',
  v8: '6.1.534.50',
  zlib: '1.2.11' }

Some details:

  1. If you install without --no-optional you get 197 packages.
  2. If you do an install with --no-optional and without an existing package-lock, you get 52 packages.
  3. If you do an install with --no-optional and the package-lock.json generated above, you get 26 packages.

The discrepancy between 2 and 3 is very disturbing. (#3 is an accurate representation of the lock-file created by #2, and should be what both #2 and #3 produce).

#1 and #2 produce the same lock-file. #3 leaves the lock-file untouched.

And even #3 includes some packages that are ONLY depended on by optional dependencies. I good example of this is hoek.