bitHound Blog

npm shrinkwrap your devDependencies too

This morning we went on a wild goose chase trying to figure out why our front-end library, Polymer, wasn't behaving nicely after a few deploys and rollbacks.

"Well that doesn't look right" - Gord

No errors in the browser console, no obvious errors in our build step. Just a broken front end. After a few initial guesses at the problem, it wasn't long before the team turned to investigating the node_modules folder.

After some clever sleuthing, the team discovered a nested npm dev dependency that broke the world after a change in version from 1.1.1 to 1.2.0. According to semver rules, that doesn't count as a breaking change. npm happily installed 1.2.0 based on the package's install rule of ^1.0.0. It shouldn't have broken anything, but it did.

Now granted – as software developers we know just how difficult is to test for every use case, and of course changes that are anticipated to be breaking still make it through. We can argue that this release should have bumped the package to 2.0.0, but not knowing all the details, it's unfair to point fingers.

So how did this sneak through? We run shrinkwrap to pin versions throughout the dependency tree, given that we care about our production dependencies most. Right? Wait. Don't we build with our devDependencies? Doesn't the output it generates run in production? Why yes, yes, it very much does.

If you want to shrinkwrap your devDependencies, you can run it with the --dev flag to include them.

npm shrinkwrap --dev  

Had we been running shrinkwrap on our devDependencies, that nested package would have been pinned to 1.1.1 and the crisis would have been averted, even if it really just delayed it.

So there you have it folks, a good case to run that shrinkwrap command on your devDependencies.

bitHound identifies risks and priorities in your Node.js projects.