Windows uses backslashes inside paths and it seems to be supported by the require function. BUT ! When you use a backslash inside the "current path syntax" (usually ./) it does not work. I found this using the require.resolve method directly.
file /test/index.js :
var test, tests = [
'./stuff/please-require-me',
'./stuff\\please-require-me',
'.\\stuff\\please-require-me'
];
for(i in tests){
try {
test = require(tests[i]);
} catch(e){
test = e.message;
}
console.log(tests[i]+' = ', test);
}
file /test/stuff/please-require-me.js :
module.exports = 'OK';
My test output :
$ node index.js
./stuff/please-require-me = OK
./stuff\please-require-me = OK
.\stuff\please-require-me = Cannot find module '.\stuff\please-require-me'
As you can see in the second test, the backslash works, but in the third test it fails because it is in the "current path syntax".
I also made a quick check to see if the .\ is supposed to work, and it does :
C:\Users\William Mcmurray>cd ./Desktop
C:\Users\William Mcmurray\Desktop>cd ../
C:\Users\William Mcmurray>cd .\Desktop
C:\Users\William Mcmurray\Desktop>
@wmcmurray Are you saying using require.resolve() directly does or doesn't work correctly?
cc @nodejs/platform-windows
@Fishrock123 Both require('.\something') and require.resolve('.\something') doesn't work correctly.
https://github.com/nodejs/node/blob/a20c70029075cab18e4ff4d27dfd95b7eda2b268/lib/module.js#L229
I'm not sure it's a bug though. require is meant to be portable, and backslashes will only work on Windows. Also module loading API is locked.
Yeah, this is not a bug. Require doesn't take file paths; it takes module paths, which are /-delimited. \ in a module path is just an error and should always fail.
@domenic Ok, that make sense. Then my second test (containing a \) should have failed too ? Adding a check to make that fail right now would be a relatively huge breaking change :confused:
Yeah, probably not worth it, so likely it's just going to stay inconsistent forever since we can't change it either way. But the intent is to only use /.
Agreed. Closing.
There's an interesting addendum here and that is that the URL specification permits \ characters being converted into / in module specifiers, so I think this handling between the .\\x and ./x\\y cases not working and working respectively is in full alignment with the browser spec.
@guybedford If that the case, shouldn't both .\\x and ./x\\y pass? If not, then I'm confused and it is confusing.
@trusktr in ES modules in browsers, .\\x is parsed as a bare specifier, and will always throw for no resolution instead of attempting to be fetched.
Most helpful comment
Yeah, probably not worth it, so likely it's just going to stay inconsistent forever since we can't change it either way. But the intent is to only use
/.