It's been that way for years, since shrinkwrap was invented.
Even the shrinkwrap file itself contained a lot of trash and generated massive diff noise. I had a file full of scripts to make the shrinkwrap file usable and even then we had (production!!!) issues due to changing subdeps. We reworked our build processes to zip & deploy the exact code that passed the tests to work around that, but it was still a massive pain that installs at different points in time would yield different trees.
When yarn came out, I deleted a folder full of hacky scripts, cut my install time by 60% and finally got deterministic installs. Needless to say, I was ecstatic.
-- edit --
Seems that npm shrikwrap -> npm i -> npm shrikwrap is not guaranteed to produce the same output.