__filename, __dirname, and others are not really globals.
Tags: javascript, node, programming
Published: 2022-10-20 19:03:33

---
title: __filename, __dirname, and others are not really globals.
published: true
description: An overview about the NodeJS module wrpapper.
tags: #javascript #nodejs #programming
cover_image: https://images.pexels.com/photos/5643148/pexels-photo-5643148.jpeg
---

> A global variable is a variable that is declared in the global scope, in other words, a variable that is visible from all other scopes.

- [mdn web docs](https://developer.mozilla.org/en-US/docs/Glossary/Global_variable)

In NodeJS we have multiple variables and global objects, some of them are only specific to Node (Buffer, Event, process) while others are part of the Javascript language (JSON, Proxy, console)

`__dirname` is a variable that tells you the path of the folder where the current javascript file lives. So `__dirname` has a different value depending on the file path where this variable it's used.

`__filename` is a variable that holds the filename of the code that it's running.

You can use both of them anywhere in your code, so they must be globals. Right? 

*Right?*

![Right meme](https://i.imgur.com/bkFvEgq.jpeg)

---

It turns out that `__dirname`, `__filename`, `exports`, `module` and even `require()` are not globals. You can use all these objects anywhere in your code, but they only exist in **the module scope**. Node does not execute our module code directly. Instead of that, code lives within a closed scope, and this scope is inside the **module wrapper**.

## Inside the module wrapper

Every module is wrapped in a function that looks like this:

```javascript
(function(exports, require, module, __filename, __dirname) {

  // Module code actually lives here

});
```

You can take a look at the module wrapper in the [Node source code](https://github.com/nodejs/node/blob/main/lib/internal/modules/cjs/loader.js#L237) But you can also check it in your terminal by running the following code:

```javascript
const Module = require('module');

console.log(Module.wrap());
```

The output should be something like this:

```
> node main.js

(function(exports, require, module, __filename, __dirname) { undefined
});
```

But what is that `undefined` after the curly brackets? Well, that is where your actual code lives. The wrapper function takes one argument, and it's the module code.

In Node source code, `wrap` function looks like this:

```javascript
Module.wrapper = [
  '(function (exports, require, module, __filename, __dirname) { ',
  '\n});',
];

let wrap = function(script) {
  return Module.wrapper[0] + script + Module.wrapper[1];
};
```

So that means that if you call `wrap` and pass some code as argument:

```javascript
const Module = require("module");

console.log(Module.wrap('console.log("hello from the module wrapper")'));
```

You will get:

```
> node main.js

(function (exports, require, module, __filename, __dirname) {    
  console.log("hello from the module wrapper")
});
```

Now that we know this, we can modify the module wrapper (just for fun, of course)

We're going to need two files. The first one will be `module.js`

```javascript
function sum(a, b) {
  return a + b;
}

console.log(sum(1, 2));
```

It'll be just a simple two-sum.

The second file we'll need, it's the one where we'll modify the module wrapper. This file will be called`main.js`

```javascript
const Module = require("module");

Module.wrap = function(script) {
  console.log('hello from the module wrapper, today we will be executing the following code:');
  console.log(script);

  return Module.wrapper[0] + script + Module.wrapper[1];
}

require('./module');
```

Here we're replacing `wrap()` function with our own. We know that this function takes the module code as argument, and should return the code wrapped.

Finally, we call `require('./module')` to import our previously created file.

Now we just need to run `node main.js` and the output should be:

```
> node main.js

hello from the module wrapper, today we will be executing the following code:
function sum(a, b) {
  return a + b;
}

console.log(sum(1,2));

3
```

Very cool, very cool.

![ok but why](https://media.tenor.com/nztR9-rSH9sAAAAC/okay-but-why.gif)

---

## Why do we need a wrapper?

[Node docs](https://nodejs.org/api/modules.html#the-module-wrapper) says it is used to keep top-level variables scoped to the current module, in that way those variables are not propagating to the global object. It is also used to provide global-looking variables like `__filename` and `__dirname`, if you think about it, those variables are related to each module, so it makes sense they not being truly globals.


That's it for today! I just wanted to share something interesting I discovered in the last few days. I'm starting to dig more and more into NodeJS source code, so probably I'll be sharing more stuff here or on [Twitter](http://twitter.com/andercodes).

Please, share the post with your friends and let me know in the comments if you know about another interesting piece of code from NodeJS source.