174

I have been using Node.js version 12.3.4, and updated it to 14.14.0 and started to receive a lot of issues which I fixed. The only thing that I don't understand is the issue

__dirname is not defined

__dirname is a core variable in Node.js as I know, was it removed in Node 14?

3
  • 5
    Is this in MJS or CJS? In MJS mode you need a shim since it works differently with import. Commented Oct 16, 2020 at 6:23
  • 2
    documentation Commented Oct 16, 2020 at 6:27
  • try use import.meta.dirname instead of __dirname (nodejs.org/api/…) Commented May 27 at 10:35

4 Answers 4

320

How are you loading the file? According to this issue, the problem arises if you load it as an ECMAScript module which do not contain __dirname.

https://github.com/nodejs/help/issues/2907#issuecomment-671782092

Following the documentation below you may be able to resolve the issue: https://nodejs.org/api/esm.html#esm_no_require_exports_module_exports_filename_dirname

import { fileURLToPath } from 'url';
import { dirname } from 'path';

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
Sign up to request clarification or add additional context in comments.

4 Comments

I was getting "dirname is not defined", so the last line I had to change to const __dirname = path.dirname(__filename);
Thank you so much. I was stuck on this. I reformatting to es6 and my 'path' import broke. Code before was something like res.status(200).sendFile(path.join(__dirname, '/public/main.js')). I used the imports you recommended and changed to res.status(200).sendFile(__dirname + '/public/main.js'). Again, thank you, thank you.
export default function fileAndDirNames(url) { const __filename = fileURLToPath(url); const __dirname = dirname(__filename); return {__filename, __dirname} } needs to be a util function
129

My code before was like below.

app.use(express.static(path.join(__dirname, 'public')));

And I got this error.

ReferenceError: __dirname is not defined in ES module scope

And I solved this by adding code below.

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

2 Comments

This only resolves the cwd of the node process, so e.g. node myscript.mjs will work but node dir/myscript.mjs will not.
I was actually trying to fix path.resolve(__dirname, "foo", "bar"), because I didn't realize that it will make the path relative anyway if you just pass it path segements -- you can simply omit the __dirname. Thanks!
49

There's usually no need to import from 'url' or 'path'.

E.g. (using ESM)

fs.readFileSync(new URL('myfile.txt', import.meta.url));

will read myfile.txt from the directory of the JavaScript file (not from the current working directory).

7 Comments

Cool solution, but doesn't feel very clear to those not in the know and/or not working in a browser context where using URL seems a bit out of place. Perhaps you could expand on when this might be particularly appropriate?
Ok, looks like I just need to update my thinking. path.resolve() only returns cwd. Other methods are long winded. URL concept is baked into ES6 modules. It seems this is the standard approach now stackoverflow.com/a/66651120/4682556. Thanks for this answer!
This returns a Buffer, if you want a string use: fs.readFileSync(new URL('myfile.txt', import.meta.url), 'utf-8');
This is awesome, thank you! No extra requires, no hacks, future proof.
@Dan Yeah, a URL is getting more true to its name: uniform resource locator. It is not necessarily limited to a resource on the web.
|
9

Got this from above link

import express from 'express';
import path from 'path';
import { fileURLToPath } from 'url';

const app = express();

//we need to change up how __dirname is used for ES6 purposes
const __dirname = path.dirname(fileURLToPath(import.meta.url));
//now please load my static html and css files for my express app, from my /dist directory
app.use(express.static(path.join(__dirname ,'dist')));

//works...

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.