This happened to me…
Twas the night before beta launch… I installed a new node module for a last minute feature and everything went haywire when the change was deployed. I reverted the code change and built again but everything was still all messed up.
Long story short, I kicked myself for not shrinkwrapping my dependencies while I still had the chance.
There really wasn’t time to figure out exactly who in the dependency tree updated what and when. The rug had been pulled out.
(An exercise to the reader, if not aware of the various ways the
node_modules folder can be put in a state that isn’t repeatable or reversible — think of the interplay between local cache and semver and new updates)
So, I needed to figure out what shrinkwrap would have been in the past — and then narrowly and selectively add the new node module which revealed all this mess but is still needed for the latest code.
The next step wasn’t obvious to me until I had banged my head into the table for a while — Let’s go back in time!
Luckily, I did follow the best practice of archiving and versioning my application deployment binaries.
(I was using Heroku, so it kinda was just there for free. But on other projects where I use Docker or Packer, I do always make sure to tag on each SHA/CI build.)
A couple of
heroku rollbacks later, I was able to
heroku run bash in and then
npm shrinkwrap && cat npm-shrinkwrap.json to get the file contents needed for my local shrinkwrap file.
After that I was able to run
npm install somemodule@someversion --save locally and I was all set! After my next commit and deploy everything worked fine.
Remember, only you can prevent improper dependency management.
But if you do forget to lock everything down, hopefully you still have those application binaries around.
— Luke Patterson, firstname.lastname@example.org