With NPM, this is not true. You can reference exact versions in every single entry in the package.json file and it doesn’t matter.
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.