__filename vs __dirname vs process.cwd()
Before we dive into the nuances of __dirname
, __filename
and process.cwd
, let’s briefly talk about how Node.js creates modules.
The Node.js module system
In Node.js, each file is treated as a module and we need to explicitly export what we want to use outside of that module (file).
The exported piece of code which can be an object, function or even a class may then be require
d in other modules of the application.
Before the code we require
is executed, Node.js wraps all of it in a function:
(function(exports, require, module, __filename, __dirname) {
// module code
});
This is why the variables we define with const
and let
in the module will stay private (they will remain inside the wrapper function’s scope) and the arguments of the wrapper function (including __dirname
and __filename
) will be local variables belonging to that module.
__dirname
__dirname
is a string and displays the directory name of the current folder. It can be used and logged as is:
console.log(__dirname); // DIRECTORY_NAME_WITH_PATH
__dirname
seems to be part of the global object but - as we have seen - it’s local and is specific to the given module!
__filename
__filename
is also a string and is the name of the current module (which is a file):
console.log(__filename); // FILE_NAME_WITH_PATH
Similarly to __dirname
, __filename
can be used as is and it exists in the module.
process.cwd()
process.cwd()
returns the current working directory of the Node.js process that is running - hence the name of the method:
console.log(process.cwd()); // DIRECTORY_NAME_OF_THE_PROCESS_WITH_PATH
This method is the odd-one-out as process.cwd()
lives in the process
module and not in the exported module itself. The process
object is a global
and as such, it can be used without require
-ing it.
Example
It’s common that __dirname
is confused with process.cwd()
. The main difference is that __dirname
is related to the module (see the wrapper function above) and process.cwd()
refers to the running process regardless of where it’s called.
In order to see the difference, we can create two files and a folder.
Let the name of the folder be dependencies
and it contains a file called dependency.js
. We will require
this module in the other file called main.js
, which is in the root folder.
So the folder structure can look like this:
|--- dependencies
| dependency.js
|--- main.js
dependency.js
contains a function that logs the dependency.js
-related __dirname
and __filename
and we call process.cwd()
as well:
// dependencies/dependency.js
const logNames = () => {
console.log('from dependency, __dirname:', __dirname);
console.log('from dependency, __filename:', __filename);
console.log('from dependency, process.cwd():', process.cwd());
}
module.exports = logNames;
We export logNames
because it will be used in main.js
, which can look like this:
// main.js
const logNames = require('./dependency/dependency');
console.log('from main, __dirname:', __dirname);
console.log('from main, __filename:', __filename);
console.log('from main, process.cwd():', process.cwd());
logNames();
We require
the exported function here, log __dirname
and __filename
(they are specific to main.js
) as well as the returned value of process.cwd()
, and then call logNames
.
Let’s now run main.js
with the node main.js
command.
We should get something similar in the console:
from main, __dirname: PATH_TO_THE_PROJECT_ROOT
from main, __filename: PATH_TO_THE_PROJECT_ROOT/main.js
from main, process.cwd(): PATH_TO_THE_PROJECT_ROOT
from dependency, __dirname: PATH_TO_THE_PROJECT_ROOT/dependency
from dependency, __filename: PATH_TO_THE_PROJECT_ROOT/dependency/dependency.js
from dependency, process.cwd(): PATH_TO_THE_PROJECT_ROOT
Both __dirname
and __filename
is specific the module they live in, therefore they return the relevant directory and file names of their modules.
But process.cwd()
returns the directory name of the current running process. Because we started the process by running the code inside main.js
, and main.js
is located in the root folder, process.cwd()
will return the path to the root.
We require
d dependency.js
in main.js
and because logNames
, which was defined in another module (dependency.js
), was called in main.js
, the returned values will be the same in both cases.
Conclusion
It’s easy to confuse __dirname
and process.cwd()
. The key difference is that __dirname
is specific to the given module (file), while process.cwd()
is a method of the global process
object returning the directory name of the file from where the process was run.
__filename
is the little brother of __dirname
with a difference of showing the name of the file instead of the folder name.
I hope that the post was helpful. Thanks for reading and see you next time.