This is the second best strategy, but:
- node makes it kind of annoying to do this, because unless you do a clean build every time (which is much slower) `package-lock.json` will get largely ignored.
- I have seen multiple projects break with semver. Just because people are supposed to avoid breaking changes in minor releases doesn't mean they actually do.
- Even if you're downloading the same version, there are scenarios where natively compiled binaries can bite you. I've run into issues where node-gyp just wouldn't work unless I downloaded a completely separate compile toolchain onto Windows and restarted the computer. If you can avoid that and have all of your dependencies be pure Javascript, you will eventually save yourself a lot of horrible dev-ops work when the "quick" install on a new VM turns into an hour long process of watching Visual Studio tools download (tools that to GP's point may not be available or compatible 10 years from now).
- And finally, sometimes you want to do work across multiple branches without an internet connection, and vendoring your dependencies allows you to check out a branch and know you have the correct dependencies even if you don't have a connection to run `npm install` with.