Sitelet https://github.com/nodejs/node/issues/5525
Skip to content

Documentation for __dirname is misleading #5525

Description

@c-f-h

The documentation for __dirname states that it gives "The name of the directory that the currently executing script resides in."

This may be taken to imply that __dirname always refers to the path of the module that was invoked as a script from the command line. However, it actually always produces the path of the current module, no matter where it was required from.

Just to clarify: assume I have modules

a.js
b/b.js

and a.js requires b.js. I run node a.js, and b.js uses its __dirname, which will refer to the b subdirectory. The current wording implies that it might actually refer to the directory that a.js is contained in since that is the "script" that I ran from the command line.

Activity

  1. added
    docIssues and PRs related to Node.js documentation.
    moduleIssues and PRs related to the module subsystem.
    on Mar 2, 2016
  2. cjihrig commented on Mar 2, 2016

    @cjihrig
    Contributor

    When b.js is running, it is the currently executing script, not a.js. If you can word it less ambiguously, a docs PR is welcome.

  3. mk-pmb commented on Dec 7, 2016

    @mk-pmb

    Please re-open, as the documentation is still (or again?) misleading even in v7.2.1: http://web.archive.org/web/20161207142244/https://nodejs.org/api/globals.html .

    To me it looks like __dirname always refers to the script in whose scope it is used, independent of whether that script is currently running. (b done shows that the script has finished before a calls the function it imported.)

    File b/b.js:

    console.log('b start', __dirname);
    module.exports = function () { console.log('b func', __dirname); };
    console.log('b done', __dirname);

    File a/a.js:

    console.log('a start', __dirname);
    var b = require('./b/b.js');
    console.log('a has required', __dirname);
    b();
    console.log('a done', __dirname);

    Output of nodejs a/a.js:

    a start /tmp/a
    b start /tmp/b
    b done /tmp/b
    a has required /tmp/a
    b func /tmp/b
    a done /tmp/a
    
  4. sam-github commented on Dec 7, 2016

    @sam-github
    Contributor

    __dirname always refers to the script in whose scope it is used, independent of whether that script is currently running

    "script use" and "script run" have same meaning, how do you think they are different? In your example, all uses of __dirname in b.js occur only when b.js is run. If b.js was not running.... console.log would not be called from b.js.

    That said, I kindof like your description, but note that its almost there already: "__dirname isn't actually a global but rather local to each module". Local is of course a reference to scope, but that is not as explicit as it could be. Also, resolved is not so obvious in its meaning.

    Would you care to PR a reword?

    I think the bigger problem is that the __dirname and __filename docs have diverged, astoundingly, their docs should be almost identical, given that __dirname is path.dirname(__filename)! That they have different verbal gymnastics to describe the same concept should be fixed.

  5. mk-pmb commented on Dec 7, 2016

    @mk-pmb

    "__dirname isn't actually a global but rather local to each module."

    Thanks for showing me, I totally missed that because I only checked the first paragraph earlier.

    In your example, all uses of __dirname in b.js occur only when b.js is run.

    You're right, and my earlier example even allowed for a much too naive reading of "use". Here's a better one where none of the scripts mention __dirname as an identifier in their code:

    $ head */*.js && echo $'\n== Test it! ==' && nodejs lab/test.js
    ==> foo/bar.js <==
    module.exports = function (x) { return eval(x); };
    
    ==> lab/test.js <==
    var remoteEval = require('../foo/bar.js'), varname;
    console.log('re:', typeof remoteEval);
    varname = [ 'me', 'rna', '__di' ].reverse().join('');
    console.log('dn:', remoteEval(varname));
    
    == Test it! ==
    re: function
    dn: /tmp/foo
    

    People less familiar with closure might really think that some part of bar.js might be running even after the "re:" log call, because they confuse to which point in time the explanation of "currently executing script" applies.

    Would you care to PR a reword?

    Nope, don't have time to word it as perfectionist as I'd expect for a node PR. ;-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    docIssues and PRs related to Node.js documentation.moduleIssues and PRs related to the module subsystem.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions