Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why dirname is not a module atribute? (__ notation)

I'm studying the basics of node. According to the documentation, both __dirname and __filename belong to module scope. As expected, both:

console.log(__dirname)
console.log(__filename)

Work, printing current dirname and filename.

But when i try calling them from module, only filename works:

console.log(module.dirname)
console.log(module.filename)

The first one prints undefined.

1 - Why console.log(module.dirname) prints undefined?

2 - I'm confused about __notation. If it's not a sugar sintax for module., what it is used for?

like image 987
abcson Avatar asked Jun 14 '26 08:06

abcson


1 Answers

Those variables are defined as arguments to a function that is wrapped around your module code like this:

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

    // Module code actually lives in here

});

This does several things:

  1. It provides a scope for your module (the function scope of the wrapper function). Any top level variables you declare in your module will actually be scoped to the module, not at the top, top scope.
  2. It provides the values of require, module, __filename and __dirname as independent variables that are unique for each module and cannot be messed with by other modules.

The properties of the module object (collected with Object.getOwnPropertyNames(module) are:

  'id',
  'exports',
  'parent',
  'filename',
  'loaded',
  'children',
  'paths'

Why dirname is not a module attribute?

The "why" would have to go into the head of the designer and discussion at the time the module system was designed. It's possible that a module object might be accessible by some other code and passing __dirname and __filename as arguments to the wrapper made it so that even something else who had access to your module object couldn't mess with __dirname and __filename. Or, it could have just been done for shortcuts in typing. Or, it could have just been a personal design choice.

Why console.log(module.dirname) prints undefined?

Because dirname is not a property of the module object itself (I have no idea why). Instead, __dirname is passed as the wrapper function argument.

I'm confused about __notation. If it's not a sugar syntax for module., what it is used for?

Usually, the _ or __ prefix is just used to make sure it doesn't accidentally collide with any regular variable declaration in the code. My guess is that the original designers of node.js envisioned existing code bases being used in modules and they wanted to lessen the chances of a variable naming collision.


Some of your question seems to be about why aren't all of these just properties of the module object. I can think of no particular reason why that wouldn't have been a perfectly normal and logical design.

To save typing, there are object lots of references to require so I can certainly see an argument for not making us all type module.require('someModuleName') every time.

And, exports is already a property of module. For example, module.exports === exports. Using it as module.exports does have some use because you can define a whole new object for the exports:

module.exports = {
    greeting: "hello",
    talk: function() {...}
};

But, you cannot do that by just reassigning the exports. This will not work:

exports = {
    greeting: "hello",
    talk: function() {...}
};

So, I guess exports is also supplied as a shortcut when you just want to do:

exports.talk = function() {...}

But, module.exports is needed if you're assigning a whole new exports object.

like image 199
jfriend00 Avatar answered Jun 16 '26 02:06

jfriend00