There is also that. But one can reference the exact version and it becomes a non issue. In a properly secure environment it might be desirable. But as with everything there are pros and cons to each approach.
Each one of those exact versioned libraries you referenced will itself likely have semantic version dependencies which may update themselves. Unless every single dependency you depend on also follows the policy of pinning to exact versions (and their dependencies do the same, and so on), you are still vulnerable (See left-pad incident, which was a sub-dependency of babel).
The only way to avoid this is the old shrinkwrap or the new package-lock.json feature.