Differences between __dirname, process.cwd, path.join and path.resolve

31 mar 20215 min read

We'll review the different ways I know to handle path and current directory in javascript For each example below we'll assume this folder structure :

app
├── main.js
└── lib
   └── script.js

process.cwd() and __dirname

  • process.cwd(): returns the absolute path to the directory from which the node command has been invoked. It is a global property.
  • __dirname : returns the absolute path to the directory containing the source file that is being executed.

With our structure above, let's assume we have the following code :

// main.js
const script = require ('./lib/script.js')
// script.js
console.log( process.cwd())
console.log(__dirname)
console.log(__dirname===process.cwd())

We invoke it from main.js

cd app && node main.js

Output:

/Users/matt/personal/test-cwd-dirname/app
/Users/matt/personal/test-cwd-dirname/app/lib
false

Now let's say we invoke it directly from the script.js

cd app && node lib/script.js

Output:

/Users/matt/personal/test-cwd-dirname/app/lib
/Users/matt/personal/test-cwd-dirname/app/lib
true

 

path.join and path.resolve

  • path.join returns a normalized path by merging two paths together. It can return an absolute path, but it doesn't necessarily always do so
  • path.resolve turns a sequence of paths or path segments into an absolute path. Consuming path from right to left and stopping at the first absolute path found

What they have in common :

  • they both return a path
  • they both take care of normalizing the path. (resolving the ../ for example or dedupping the /)

When are they equivalent :

  • When you pass them an absolute path as the only argument
console.log(path.join('/ssl')); => "/ssl"
console.log(path.resolve('/ssl')); => "/ssl"
  • When you pass them an absolute path followed by some non-absolute extra path segment :
console.log(path.join(__dirname, some, dir)) === console.log(path.resolve(__dirname, some, dir))

What if you don't provide arguments :

Let's assume we use the same folder structure as above with the following script.js file

app
├── main.js
└── lib
   └── script.js
// script.js
console.log(path.join());
console.log(path.resolve());

We invoke it from main.js

cd app && node main.js

Output:

.
/Users/matt/personal/test-cwd-dirname/app

Now let's say we invoke it directly from the script.js

cd app && node lib/script.js

Output:

.
/Users/matt/personal/test-cwd-dirname/app

We can see that path.resolve when not provided any argument will yield the same result as process.cwd()

Hope this helped you clarify the main differences of those nice utilities, as it helped me.

Ressources :