Because then they'd have to change the semantics of how `require()` works. As it is, node packages are not version aware at runtime. Instead NPM is designed to place packages such that any library will have the correct version first in their load path.
Changing the directory structure to encode versions is probably the Right Way in a grand sense, but it's a much more substantial change than just promoting packages by default.
I thought about that, but clearly they have enough information to figure out whether to load the package from the top level or a nested directory. (I'm guessing simply by bubbling up and looking for the "node_packages" directory.)
It doesn't seem too big of a leap to do it the way I was suggesting.
Either bubble up and look for "node_packages", but this time store a symlink there, or add a dot file that tells you "this is where I found package.json".
I'm sure there was a reason they didn't go for either of those solutions because I've followed the team's discussions when they were iojs, and they have very smart people. I was just curious about the reasoning :)
The information may be available, but ultimately the work would have to be done by node, not npm, and it seems reasonable to not want to change such a fundamental node behavior, especially just to support a change in npm.
That doesn't handle peer dependencies. Those are resolved by walking up the filesystem. You can't walk up the file system with a symlinked structure. A single npm can be resolving different peer dependencies depending on where it is in the tree.
Read the next-highest package.json file for whatever code is executing (dependencies copy their package.json file when they install), find the dependency listing in there, with the desired version constraint. If none exists (i.e. the dependency was installed manually), take wahtever is the highest version by default. If that's not what the developer wants, it's their own fault for not specifying the dependency in their package file.
When your actual Node .js file runs `require('a')`, it has no context to determine which version it is requiring. To expect Node to look for a package.json file at runtime is absurd. This presents a problem.
I'm guessing the current behavior for require is to bubble up the directory structure and look for "node_packages".
So resolving things at runtime is already happening.
I agree using package.json at runtime is not the best solution though.
A way to keep things clean and avoid using package.json is to use symlinks instead of downloading a fresh copy, which would make putting everything at the top level a possibility.
I'm sure that option was considered, but I'm curious about why it was not taken.
I suppose I should look at the discussion notes. Hope I'll remember to do that when I'm home!
Why is this absurd? Order-dependent installation and massive node_modules trees seem a lot more absurd to me. Why not just have node parse all the package.json's (or, perhaps, npm-shrinkwrap.json) at startup time? Then `require` could easily parse that and know what dependency version from the flat node_modules to deliver.
Why not always store packages at the top level, and create a directory for each version that's required?
For example: directory "A" contains two subdirectories: "v0.1.0" and "v0.1.1"