Committing downloaded packages is not a bad practice. Yes, it can be a bit big, but otherwise I don't see much problem with it. You will be always sure that the installed packages are compatible with each other.
To be sure everything that we know works together we use things like npm-shrinkwrap files. We don't like it because it makes the git changelogs a lot bigger and almost unreadable if you want to compare a pull request.
Yes the way you should do it is with shrinwrap to ensure the consistency of your dependencies. As for the actual files if you depend on it you should have your own npm repo caching them that you deploy from and have that mirror the public one.
but for small projects or quick deploys absolutely just go ahead and commit the modules.