Why is __dirname not defined in node REPL?

From the node manual I see that I can get the directory of a file with __dirname, but from the REPL this seems to be undefined. Is this a misunderstanding on my side or where is the error?

$ node > console.log(__dirname) ReferenceError: __dirname is not defined at repl:1:14 at REPLServer.eval (repl.js:80:21) at Interface.<anonymous> (repl.js:182:12) at Interface.emit (events.js:67:17) at Interface._onLine (readline.js:162:10) at Interface._line (readline.js:426:8) at Interface._ttyWrite (readline.js:603:14) at ReadStream.<anonymous> (readline.js:82:12) at ReadStream.emit (events.js:88:20) at ReadStream._emitKey (tty.js:320:10) 
3

11 Answers

__dirname is only defined in scripts. It's not available in REPL.

try make a script a.js

console.log(__dirname); 

and run it:

node a.js 

you will see __dirname printed.

Added background explanation: __dirname means 'The directory of this script'. In REPL, you don't have a script. Hence, __dirname would not have any real meaning.

6

Building on the existing answers here, you could define this in your REPL:

__dirname = path.resolve(path.dirname('')); 

Or:

__dirname = path.resolve(); 

If no path segments are passed, path.resolve() will return the absolute path of the current working directory.


Or @Jthorpe's alternatives:

__dirname = process.cwd(); __dirname = fs.realpathSync('.'); __dirname = process.env.PWD 
3

If you are using Node.js modules, __dirname and __filename don't exist.

From the Node.js documentation:

No require, exports, module.exports, __filename, __dirname

These CommonJS variables are not available in ES modules.

require can be imported into an ES module using module.createRequire().

Equivalents of __filename and __dirname can be created inside of each file via import.meta.url:

import { fileURLToPath } from 'url'; import { dirname } from 'path'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); 

4

In ES6 use:

import path from 'path'; const __dirname = path.resolve(); 

also available when node is called with --experimental-modules

6

-> At ES6 version use :

import path from "path" const __dirname = path.resolve(); 

-> And use it like this for example:

res.sendFile(path.join(__dirname ,'views','shop.html')) 
1

As @qiao said, you can't use __dirname in the node repl. However, if you need need this value in the console, you can use path.resolve() or path.dirname(). Although, path.dirname() will just give you a "." so, probably not that helpful. Be sure to require('path').

I was also trying to join my path using path.join(__dirname, 'access.log') but it was throwing the same error.

Here is how I fixed it:

I first imported the path package and declared a variable named __dirname, then called the resolve path method.

In CommonJS

var path = require("path"); var __dirname = path.resolve(); 

In ES6+

import path from 'path'; const __dirname = path.resolve(); 

Happy coding.......

2

If you got node __dirname not defined with node --experimental-modules, you can do :

const __dirname = path.dirname(import.meta.url) .replace(/^file:\/\/\//, '') // can be usefull 

Because othe example, work only with current/pwd directory not other directory.

Seems like you could also do this:

__dirname=fs.realpathSync('.'); 

of course, dont forget fs=require('fs')

(it's not really global in node scripts exactly, its just defined on the module level)

1

I was running a script from batch file as SYSTEM user and all variables like process.cwd() , path.resolve() and all other methods would give me path to C:\Windows\System32 folder instead of actual path. During experiments I noticed that when an error is thrown the stack contains a true path to the node file.

Here's a very hacky way to get true path by triggering an error and extracting path from e.stack. Do not use.

// this should be the name of currently executed file const currentFilename = 'index.js'; function veryHackyGetFolder() { try { throw new Error(); } catch(e) { const fullMsg = e.stack.toString(); const beginning = fullMsg.indexOf('file:///') + 8; const end = fullMsg.indexOf('\/' + currentFilename); const dir = fullMsg.substr(beginning, end - beginning).replace(/\//g, '\\'); return dir; } } 

Usage

const dir = veryHackyGetFolder(); 
3

Though its not the solution to this problem I would like to add it as it may help others.

You should have two underscores before dirname, not one underscore (__dirname not _dirname).

NodeJS Docs

1

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like