69

I have been using Node version 12.3.4 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 as I know, Is it removed in Node 14?

Eduard
  • 1,168
  • 1
  • 7
  • 13
  • 3
    Is this in MJS or CJS? In MJS mode you need [a shim](https://stackoverflow.com/questions/46745014/alternative-for-dirname-in-node-when-using-the-experimental-modules-flag) since it works differently with `import`. – tadman Oct 16 '20 at 06:23
  • 2
    [documentation](https://nodejs.org/api/esm.html#esm_no_require_exports_module_exports_filename_dirname) – Jaromanda X Oct 16 '20 at 06:27

4 Answers4

129

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);
adlopez15
  • 2,229
  • 2
  • 11
  • 18
70

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();
padaleiana
  • 687
  • 1
  • 14
  • 22
Jiyoon Hur
  • 858
  • 4
  • 4
26

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).

ChrisV
  • 8,274
  • 3
  • 46
  • 38
  • 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? – Dan Sep 10 '21 at 22:03
  • 1
    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 https://stackoverflow.com/a/66651120/4682556. Thanks for this answer! – Dan Sep 10 '21 at 22:11
  • 1
    This returns a `Buffer`, if you want a string use: `fs.readFileSync(new URL('myfile.txt', import.meta.url), 'utf-8');` – Michael Stramel Oct 06 '21 at 22:27
  • This is awesome, thank you! No extra requires, no hacks, future proof. – Tomáš Kafka Nov 19 '21 at 15:45
0

A quick fix (depending on your project) would be to ensure that "type": "module" does not exist in your package.json file

Nathanael
  • 999
  • 2
  • 15
  • 36