You want some way to define package versions in your repository, so that you can check out an earlier commit or a different branch and still have a working build. Because you do often need to adjust the code in your repo when dependencies get updated.
And going upwards from there, I think that languages are just a point where it's quite natural for this to be solved, since the language creators care to build up an ecosystem and it does help when you can make language-specific assumptions.
I do think, it's possible to create a package manager that spans across programming languages, like Nix is starting to be viable for.
But you need that to be ready when a new programming language is starting to take off. For all the languages you listed, that choice was made many years ago and you can't easily reverse it.
