I loathe loathe loathe dependency management, especially on projects with large numbers of dependencies. It takes forever, is always confusing, and I'm never quite sure that I'm doing it correctly.
Updating dependencies sounds simple but it's something we're not usually taught. I always feel like I'm figuring it out on my own. When I finally do get a major library updated, I breathe a sigh of relief and feel lucky that all my stuff still works.
So this is the post I wish I had when I was learning how to do this. There is more than one way to peel a potato so you may know different strategies, but this is how I approach it and hopefully will get you going.
- Note: I have officially switched from
npmso this post will refer to
npmthroughout. For context, this post explains many dev's experiences coming back to npm and as of v7, npm handles peer dependencies automatically.
Choose 1 dependency to update
When I'm starting to update my dependencies, I never want to update them all at once. Updating them all in one go can result in a spaghetti mess of errors and warnings and confusing mismatched versions.
I choose one dependency to update and start there. By the time I'm done updating that single dependency, I'll most likely have touched many others that depend on it either explicitly or implicitly.
Update to latest minor version
Before I worry about jumping a major version, I like to update my chosen dependency as much as possible while respecting the current semver in the
package.json. Said another way, I jump to the highest minor version while keeping the same major version.
npm update package-name will do this for you automatically.
Run your application
At this point, you will probably be fine. Since you didn't jump any major versions, your app should still run. However, you may see a lot of warnings in your console. Most often these will be deprecation warnings or dependency warnings.
Deprecation warnings are informing you about features you are using that soon won't be available, most likely in the next major version of a package. These warnings will often tell you or link you to documentation on how to remove the deprecated functionality and replace it with the supported alternative.
Dependency warnings may tell you about unmet peer dependencies (less likely if you are using npm >= v7) or incompatible package versions after your update. Read what the warnings are telling you and resolve them.
If you have unmet peer dependencies, you'll have to choose to explicitly install the needed dependencies or ignore them. This can happen if a dependent library has fallen behind the library you're updating.
Sometimes this can be because it's no longer maintained or the library hasn't been tested and updated with the newer version. In either case, you'll need to decide to explicitly install the version it's asking for or ignore it.
npm install email@example.com where
x.x.x is the required version number will update the package to the specified version.
When you see errors and warnings in the console, don't panic! Slow down and read what they are telling you. Google the warning if you need to.
It's important to resolve as many of the errors and warnings you see at this step because it will make the rest of the upgrade much easier.
Once you have all of your errors and warnings resolved and the code is working, commit it! There's nothing worse than forgetting to commit incremental, working steps of an upgrade then realizing that you broke something and you can't go back because the changes in
package-lock.json are too numerous and hard to understand.
Small incremental commits during an upgrade are a huge timesaver if you try to upgrade too many versions at once. You can stash or check out what broke and get back to the most recent working version easily.
Review the documentation
Before you upgrade your chosen dependency to the next major version, review their release notes for breaking changes. Every well-maintained library will have release notes for all their versions and will document what to expect when you jump a major version.
Look at their breaking changes and assess your codebase to see if you will be affected by them. You'll want to know if there are any changes you won't be able to remediate before you upgrade. Sometimes we are using functionality in a lower version that is removed in the next version and we need time to investigate other libraries or solutions.
Bump the major version
Now you're ready to update your chosen dependency to the next major version. You can do this by editing the
package.json directly and specifying the major version
"package-name": "^3.0.0 and running
npm install. This will install the latest package within that major version.
If you don't need to upgrade multiple major versions and you are updating to the latest, you can run
npm install package-name@latest.
Now you'll want to resolve any of the documented breaking changes that affect this codebase. Follow the directions in the documentation. Once you think you have everything resolved, run the app and go back to Step 3. Once you have a clean console, free from errors and warnings (or as free as you can make it), commit your code.
You did it! You successfully updated a dependency by a full major version. And you probably updated a lot more packages than you expected. If you have more dependencies that you want to update, feel free to start at Step 1 and repeat this process until you have an up-to-date app 🌈