Nǐ hǎo, I'm Julia.

How to Upgrade an npm Package's Dependencies with Yarn

#devtools #javascript

4 min read

The repos I work with have Dependabot set up. For those unfamiliar with this, it's a tool that comes with GitHub that automatically identifies out of date dependencies in your repo. Depending on your configuration and type of dependency, Dependabot can also open PRs that automatically does the update for you. This is especially useful for ensuring that your app is kept up to date from a security and vulnerability perspective.

All in all, Dependabot works pretty well. There will be times however, when I'll need to do manual upgrades myself, either because there's a version mismatch between shared dependencies that cannot be resolved, or because a major / minor version upgrade is required to fix the vulnerability, and my semantic version requirement in package.json doesn't allow for this.

So what do you do if you need to manually upgrade the dependency of your app's dependencies (i.e. your app's deep dependencies)? Before answering that, let me first take a step back for those brand new to JavaScript applications and yarn.

How does yarn and package.json work?

What you'll probably have is a package.json file listing the npm packages (dependencies) your app uses.

package.json file example

If you want to upgrade your app's direct dependencies (let's say gray-matter in this case), what you can do is run yarn upgrade gray-matter in your command line (in the directory where your package.json file resides). Alternatively (which tends to be what I do), amend your package.json file with the specific version of the package you want and run yarn. This allows me to be precise in the exact version I install (although you can also do this with the first method by running yarn upgrade gray-matter@4.0.3 for instance).

The first time you install your node packages for your application, you'll see a yarn.lock file appear. This file lists out all the versions of the direct and indirect dependencies used throughout your app. Whenever the yarn command is run, the package.json and yarn.lock files are compared, and missing / updated / downgraded dependencies are downloaded into the node_modules folder.

How do you upgrade sub-dependencies?

As you won't be able to do this via package.json, you'll need to go via the yarn.lock file instead. Let's say we want to upgrade the mime-db sub-dependency. In yarn.lock, make a search for mime-db. You'll want to find the portion of code where the package itself is defined (ignore instances where other packages reference mime-db as a dependency to use). What you should see is mime-db@versionxxx, along with the version, resolved link and integrity hash. You might see multiple version of mime-db, and that's fine.

To force an update, just delete all of these and run yarn again. Note that this will only upgrade the mime-db package to the latest minor or patch version.

yarn.lock file example

What if a minor version upgrade doesn't solve the security issue?

This gets messy. What you'll essentially need to do is understand all the dependency chains that require this out of date package. You can do this by running yarn why mime-db. For each dependency chain, you'll need to go package by package, and upgrade each one individually as needed, using the step above in the first instance.

If that doesn't work, npm provides an overrides setting that allows you to specify which version of a package to use in a dependency tree. You can read more about configuration options here. Note that the dependency version you want might not play nicely with the existing package, so you'll be doing this at your own risk.

The ideal solution would probably be to change the package dependency at the source, by opening a pull request, with well-tested changes, so this can benefit the entire community. 😊

© 2016-2023 Julia Tan · Powered by Next JS.