Understanding directory references in Node.js#

So, there are three different ways to refer to directories in Node.js; namely - dot notation (./ and ../), __dirname, and process.cwd(). While all of them might seem to refer to the same thing, they can become a source of confusion and bugs, if they are not understood well.

The usage of ./ and ../ come from operating system relative directory dot notations. ./ refers to the present working directory (a.k.a current working directory), ../ refers to the parent of the present working directory.

Let's examine how they work.

Create a directory named base with the following tree under it:

.
├── app.js
└── /one
    ├── one.js
    └── /two
        └── two.js
app.js
var fs = require('fs');
console.log('------ base-app ------');
console.log('./app.js: ', fs.existsSync('./app.js'));
console.log('__dirname: ', __dirname);
console.log('process.cwd(): ', process.cwd());

require('./one/one.js');
one.js
var fs = require('fs');
console.log('------ mod-one ------');
console.log('./one.js: ', fs.existsSync('./one.js'));
console.log('__dirname: ', __dirname);
console.log('process.cwd(): ', process.cwd());

require('./two/two.js');
two.js
var fs = require('fs');
console.log('------ mod-two ------');
console.log('./two.js: ', fs.existsSync('./two.js'));
console.log('__dirname: ', __dirname);
console.log('process.cwd(): ', process.cwd());

Execute the files in each directory, and observe their output carefully.

In the directory base:

$ node app.js

------ base-app ------
./app.js:  true
__dirname:  /Projects/base
process.cwd():  /Projects/base
------ mod-one ------
./one.js:  false
__dirname:  /Projects/base/one
process.cwd():  /Projects/base
------ mod-two ------
./two.js:  false
__dirname:  /Projects/base/one/two
process.cwd():  /Projects/base

In the directory one:

$ node one.js

------ mod-one ------
./one.js:  true
__dirname:  /Projects/base/one
process.cwd():  /Projects/base/one
------ mod-two ------
./two.js:  false
__dirname:  /Projects/base/one/two
process.cwd():  /Projects/base/one

In the directory two:

$ node two.js

------ mod-two ------
./two.js:  true
__dirname:  /Projects/base/one/two
process.cwd():  /Projects/base/one/two

Now, run one.js from the directory two:

$ node ../one.js

------ mod-one ------
./one.js:  false
__dirname:  /Projects/base/one
process.cwd():  /Projects/base/one/two
------ mod-two ------
./two.js:  true
__dirname:  /Projects/base/one/two
process.cwd():  /Projects/base/one/two

Did you notice anything noteworthy?

./ and process.cwd() refers to the directory on which the node command was called. It does not refer to the directory of the file being executed.

__dirname refers to the directory where the file being executed resides.

So be careful, the next time you use ./, process.cwd(), or __dirname. Make sure what you are using is exactly what you want.

References#

  1. Node.js - __dirname
  2. IBM - dot notation