You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
require.resolve with paths and non-existent directory returns incorrect local file when using ./ #18408
It seems to be a matter of whether or not the provided paths are searched, or if they are just used as a starting point for the resolution. In your example, I think bare should throw, because running require('index.js') from the exists directory would throw.
If that were the case wouldn't one have to try/catch every directory in the paths array individually if the directories could be missing? Personally I'm using require.resolve in this case to find where an entry point is among multiple possible source directories. I thought that was what require.resolve with the paths option was specifically for since it only returns one file.
If that were the case wouldn't one have to try/catch every directory in the paths array individually if the directories could be missing?
No. An exception is only thrown if no match is found after trying all paths. This is how require() and require.resolve() work. In your original example, the non-existent ./imaginary path doesn't change anything.
Personally I'm using require.resolve in this case to find where an entry point is among multiple possible source directories. I thought that was what require.resolve with the paths option was specifically for since it only returns one file.
require.resolve() acts like require(), but returns the resolved path, instead of the actual module. The paths argument is supposed to be equivalent to calling require.resolve() from each of the provided paths. The issue you're running into is that each of the provided paths is ALSO searched. cjihrig@63beb8c undoes that behavior.
The behavior remains. I'm not sure if the existing behavior is considered a bug or not. Personally, I think it's a bug. I suppose I could PR cjihrig@63beb8c.
As explained in here I feel this behavior should be considered a bug. If you try to do require.resolve from folder A passing folder B to its paths option, you would expect it to behave same as if you called require.resolve inside folder B without paths option. That is not the case in the current situation.
Calling require.resolve('./') inside folder B will resolve to path/to/B/index.js if it exists or error out with MODULE_NOT_FOUND.
If you call require.resolve('./', { paths: ['path/to/B'] }) inside folder A it will resolve to path/to/B/index.js if it exists, if not then to root/index.js if it exist and only then error out if both files are not found. That was unexpected behavior for me. Also, there is no mentioning of this behavior in documentation unless the root folder is considered to be part of GLOBAL_FOLDERS. But, even if it is, then why it's not included when calling require.resolve without paths option and be resolved in both cases equally.
Due to this behavior I have to consider paths options unreliable and fallback to using path.resolve('path/to/B', './') and have my own custom logic to parse the request and figure out if it's relative or absolute. Also, while at this, I feel options should be added to require.resolve.paths so we can get resolvement paths when we provide paths option.
Activity
fix(webpack): remove `./` from resolved file name
cjihrig commentedon Jan 27, 2018
I think the fix for this would be cjihrig@63beb8c.
It seems to be a matter of whether or not the provided paths are searched, or if they are just used as a starting point for the resolution. In your example, I think
bareshould throw, because runningrequire('index.js')from theexistsdirectory would throw.BrainBacon commentedon Jan 27, 2018
If that were the case wouldn't one have to try/catch every directory in the paths array individually if the directories could be missing? Personally I'm using require.resolve in this case to find where an entry point is among multiple possible source directories. I thought that was what require.resolve with the paths option was specifically for since it only returns one file.
cjihrig commentedon Jan 27, 2018
No. An exception is only thrown if no match is found after trying all paths. This is how
require()andrequire.resolve()work. In your original example, the non-existent./imaginarypath doesn't change anything.require.resolve()acts likerequire(), but returns the resolved path, instead of the actual module. Thepathsargument is supposed to be equivalent to callingrequire.resolve()from each of the provided paths. The issue you're running into is that each of the provided paths is ALSO searched. cjihrig@63beb8c undoes that behavior.BrainBacon commentedon Jan 27, 2018
Oh, excellent. Thank you for the clarification.
gireeshpunathil commentedon Apr 10, 2018
Is this resolved, and a close candidate?
cjihrig commentedon Apr 10, 2018
The behavior remains. I'm not sure if the existing behavior is considered a bug or not. Personally, I think it's a bug. I suppose I could PR cjihrig@63beb8c.
niksajanjic commentedon Oct 15, 2018
As explained in here I feel this behavior should be considered a bug. If you try to do
require.resolvefrom folder A passing folder B to its paths option, you would expect it to behave same as if you calledrequire.resolveinside folder B without paths option. That is not the case in the current situation.Calling
require.resolve('./')inside folder B will resolve topath/to/B/index.jsif it exists or error out withMODULE_NOT_FOUND.If you call
require.resolve('./', { paths: ['path/to/B'] })inside folder A it will resolve topath/to/B/index.jsif it exists, if not then toroot/index.jsif it exist and only then error out if both files are not found. That was unexpected behavior for me. Also, there is no mentioning of this behavior in documentation unless the root folder is considered to be part of GLOBAL_FOLDERS. But, even if it is, then why it's not included when callingrequire.resolvewithout paths option and be resolved in both cases equally.Due to this behavior I have to consider paths options unreliable and fallback to using
path.resolve('path/to/B', './')and have my own custom logic to parse the request and figure out if it's relative or absolute. Also, while at this, I feel options should be added torequire.resolve.pathsso we can get resolvement paths when we provide paths option.cjihrig commentedon Oct 15, 2018
I'll open the PR a little bit later today. It will probably have to be a semver major change though.
cjihrig commentedon Oct 16, 2018
@niksajanjic can you try building Node with #23683 and see if that fixes your issue?
niksajanjic commentedon Oct 16, 2018
I'll give it a shot next day or 2 and get back to you.
module: don't search in require.resolve.paths
module: don't search in require.resolve.paths