A few days ago I accidentally ran Node.js from the command line with a wrong argument. I had a script – call it myscript.js
– in a directory called myscript
. I typed node mys
in the directory one level higher, pressed tab
and ended up with node myscript/
, then pressed enter
and got an error (obviously). So, I then cd
‘d into the right directory and (without much thinking) pressed up
twice and enter
. To my surprise, the script ran.
What is going on?
I tried to find some information about it in the docs or on the Internet, but to no avail. I even did some grepping in the sources, with the same (lack of) result. So, I can only guess what is going on. My suspicion is that when Node.js gets a script filename as a parameter, it runs (the equivalent of) path.resolve
on it. This means that a directory name and ..
cancel out (even if the directory is non-existent – path.resolve
seems not to actually look at the disk), the single-dot components are left out, the trailing slashes are removed, and if the resulting path is relative, the path to the current directory is added in front of it. Then, if the file with the constructed name exists, it is called, and if not, Node.js checks if adding .js
makes it into an existing file.
This means a few things. For instance, if you are in a directory whose sole contents is a Node.js script, called myscript.js
, then any of these commands will run it:
node myscript.js node myscript node non_existent_dir/../myscript node non_existent_dir/../myscript.js node myscript.js/ node myscript.js/.
Also, you can run a script called myscript.js.js
by saying node
myscript.js
, and if you have two files, myscript
and myscript.js
, then node myscript
runs the former.
I’m not sure if any of this is useful to anyone, but here it is – now you know.