Packages are versioned, using a method called Semantic Versioning. The package manager npm uses semantic versioning to distribute new versions of packages, for your codebases to consume.
Where Issues Occur
When using npm
to install packages for a project, the package and the version you have installed will be tracked inside of the package.json
file. However, these package versions are usually prefixed with either a ^
(caret) or a ~
(tilde). In short:
^x.x.x
– The caret will install the package to the most recent major version.~x.x.x
– The tilde will install the package to the most recent minor version.
This can result in discrepancies between what you think is being installed, and what actually gets installed. Your locally installed packages might be right, but your CI might be installing the latest version that satisfies the rules described above.
In our case, a minor version change in the TypeScript Project caused a breaking change in a project of ours, but the package.json
file allowed this to happen by design. Luckily, we caught this before it went to production!
NPM Vet
One way to check which version of a package has been installed is to read the version from node_modules/{package name}/package.json
. If you have multiple packages, or want to automate your CI builds to check for you, you can use NPM Vet to make this process much, much easier.
NPM Vet allows you to quickly visualise the difference between versions defined in your package.json
and versions installed in the node_modules
folder. It will also show you whether the version has been ‘locked’, or still remains prone to the issues described in the previous section.
To stop these mismatches from creeping up on us, we can lock down our package.json
file so that package versions installed are exactly to our liking. To do this, we can remove the tilde or caret before the version number defined in our package.json
file. After, use NPM Vet to confirm all your packages are locked.
Continuous Integration
To prevent these issues occurring for us again, we fitted our CI builds with NPM Vet, in which our builds will fail if any version mismatches are found. Therefore, we won’t be shipping any undiscovered issues to our test or production environments. Delightful!
NPM Vet ships with a CI renderer built in, so we added a build step and ran the following.
$ npmvet -r ci
Getting Started & Contributing
Information regarding installing and using NPM Vet can be found on the GitHub Page. We’re looking forwarding to hearing how people use NPM Vet. If you’re interested in contributing to the project, feel free to file an Issue or submit a Pull Request!