How to update dependencies of dependencies using npm

Viewed 30645

I'm very wondered that I can't find an answer to this simple question. Also I'm very wondered that npm update does not solve this.

I can't post my complete dependency tree here but let me describe my issue anyway:

minimist is outdated (version 1.2.0) and has a security vulnerability in this version. The packages require minimist define the dependency as ^1.2.0 - so it is compatible with 1.2.2.

The common solution is to put it to package.json within devDependencies or dependencies with ^1.2.2. I don't want to put it into package.json. I feel like npm update should also update indirect dependencies.

Am I missing something?

Here you can see my package-lock.json: https://github.com/tflori/riki-community/blob/master/package-lock.json

And the output of npm ls minimist:

riki-community@ /home/iras/work/projects/riki/community
├─┬ awesome-typescript-loader@5.2.1
│ ├─┬ loader-utils@1.2.3
│ │ └─┬ json5@1.0.1
│ │   └── minimist@1.2.0  deduped
│ └─┬ mkdirp@0.5.1
│   └── minimist@0.0.8 
├─┬ jest@25.1.0
│ └─┬ @jest/core@25.1.0
│   ├─┬ @jest/transform@25.1.0
│   │ └─┬ @babel/core@7.8.7
│   │   └─┬ json5@2.1.2
│   │     └── minimist@1.2.5 
│   └─┬ jest-haste-map@25.1.0
│     └─┬ sane@4.1.0
│       ├─┬ @cnakazawa/watch@1.0.4
│       │ └── minimist@1.2.0  deduped
│       └── minimist@1.2.0  deduped
├─┬ node-sass@4.13.1
│ └─┬ meow@3.7.0
│   └── minimist@1.2.0 
├─┬ ts-jest@25.2.1
│ └─┬ json5@2.1.2
│   └── minimist@1.2.5 
├─┬ tsconfig-paths-webpack-plugin@3.2.0
│ └─┬ tsconfig-paths@3.8.0
│   └── minimist@1.2.0  deduped
└─┬ webpack@4.42.0
  └─┬ watchpack@1.6.0
    └─┬ chokidar@2.1.8
      └─┬ UNMET OPTIONAL DEPENDENCY fsevents@1.2.9
        └─┬ UNMET OPTIONAL DEPENDENCY node-pre-gyp@0.12.0
          ├─┬ UNMET OPTIONAL DEPENDENCY mkdirp@0.5.1
          │ └── UNMET OPTIONAL DEPENDENCY minimist@0.0.8 
          └─┬ UNMET OPTIONAL DEPENDENCY rc@1.2.8
            └── UNMET OPTIONAL DEPENDENCY minimist@1.2.0 
4 Answers

The problem is the depth. From the documentation:

As of npm@2.6.1, the npm update will only inspect top-level packages. Prior versions of npm would also recursively inspect all dependencies. To get the old behavior, use npm --depth 9999 update.

So we have to provide the depth that we want to update. In my case, the 9999 depth took too long and I cancelled it. But a --depth 5 was enough.

npm update --depth 5

If that does still not update the dependency then you have to manually change the package-lock.json.

Open the package-lock.json and find all occurrences of "minimist": { and remove the object.

Example:

Change this:

      "dependencies": {
        "minimist": {
          "version": "1.2.0",
          "bundled": true,
          "dev": true,
          "optional": true
        }
      }

to that:

      "dependencies": {
      }

And run npm install again.

As of npm v7.0.0, running npm update will always update all packages, not just the ones specified in root package.json file. NPM has removed --depth option from npm update command and changed its behavior.

Note: it is still possible that some underlying package is specifying an outdated version as a dependency, which will prevent npm update from installing the latest version. You don't have many options, other than forcing a resolution to a more recent version.

I also needed to manually change the minimist version to "^1.2.5" from "0.0.8" for the dependency of "mkdirp"

If you want to update all dependencies recursively, I believe this is the fastest, most robust solution:

First, make sure you commit any changes in case you run into problems with git commit package*.json. Second, update any of your direct dependencies as desired with npm outdated and npm update xyz

Now, update all package versions with a clean build of package-lock.json:

# remove current node_modules/ and package-lock.json
rm -rf package-lock.json node_modules/

# rebuild package-lock.json the the semantically-compatible 
# latest package versions & install node_modules/
npm install

# ensure nothing broke
npm test

If there is a problem, roll back:

rm -rf package-lock.json node_modules/
git checkout package*.json
npm install

P.S. This technique has worked well for me, but I'm always learning more about NPM & package-lock. I'd love to hear from other NPM experts on this technique.

Related