-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
node resolution algorithm with NODE_PATH resolves in wrong order #1117
Comments
Thanks for the report, and especially for making it easy to reproduce. The reason why this works this way is that I implemented esbuild's path resolution by following node's own documentation: https://nodejs.org/api/modules.html#modules_all_together. This is the relevant part:
So according to the documentation, the algorithm is const nodePath = isWindows ? process.env.NODE_PATH : safeGetenv('NODE_PATH');
...
const paths = [path.resolve(prefixDir, 'lib', 'node')];
...
if (nodePath) {
ArrayPrototypeUnshiftApply(paths, ArrayPrototypeFilter(
StringPrototypeSplit(nodePath, path.delimiter),
Boolean
));
}
modulePaths = paths;
...
let paths = modulePaths;
if (parent?.paths?.length) {
paths = ArrayPrototypeConcat(parent.paths, paths);
} In this case the path list is In any case, fixing this in esbuild should be straightforward. |
wow interesting, I did not read the documentation 😅, I also just looked at the nodejs implementation thanks for also filling a nodejs bug :) |
Just to note, global folders and NODE_PATH (both have been deprecated for a very long long long time) are not supported by |
@bmeck I know :) I really like the feature in esbuild though, in webpack we used the
the "other paths for dependencies" can now be injected via the |
Interesting... this release In Webpack, we were doing a |
You can insert whatever custom path resolution logic you need with a plugin: https://esbuild.github.io/plugins/#resolve-callbacks. |
@evanw does this mean I have to reeimplement the node resolution algorithm (with package.json parsing, browser, module resolvinge etc..) or is it also possible to just delegate the resolution with a new base path to the built-in resolver? If I return a path it is handeld as "resolved" and the built-in resolver does not kick in... maybe this would be a nice feature, delgate to the built-in resolver with a new path so that NODE_PATH does not need to be used for such scenarios? |
Others have already done that work. For example there is https://www.npmjs.com/package/enhanced-resolve from Webpack. |
Hi
I found a bug in the resolution algorithm, node_modules folders in the same directory and in parent directories should have precedence over modules directly in NODE_PATH
here is a repository to reproduce this bug:
https://github.com/mzeiher/esbuild-node-path-bug
there are 2 versions of "package-c" in the directory which is loaded via NODE_PATH, one which exports "version 1.0.0" directly in the "NODE_PATH" directory and one in the node_modules folder in the package-b module, the package-b module uses package-c and I would expect that the require (or import) would load the package-c file in the node_modules directory within package-b, instead esbuild resolves to the package-c module in the root of the "NODE_PATH" directory.
You can reproduce this bug with the linked repository:
How to reproduce:
node resolves the "package-c" dependency to the node_modules folder relative to the using module, esbuild resolves the "package-c" dependency to the module in the root of the NODE_PATH variable (just check the bundled out.js)
Maybe esbuild should mimic the resolution algorithm of nodejs?
Tested with esbuild 0.11.5 and node 14.15.1 on a windows PC
The text was updated successfully, but these errors were encountered: