About “__dirname is not defined in ES module scope” in JavaScript
Tags: javascript, webdev, beginners
Published: 2023-02-05 15:11:19

> ✋ **Update:** This post was originally published on my blog [decodingweb.dev](https://www.decodingweb.dev), where you can read the [latest version](https://www.decodingweb.dev/dirname-is-not-defined-in-es-module-scope-fix) for a 💯 user experience. _~reza_

The error "`__dirname` is not defined in ES module scope" means you're using `__dirname` global variable in an ES (ECMAScript) module.

Here’s what the error look like:

```
file:///dwd/sandbox/utils.js:2
 return __dirname
 ^

ReferenceError: __dirname is not defined in ES module scope
This file is being treated as an ES module because it has a '.js' file extension and '/home/dwd/sandbox/package.json' contains type: module. To treat it as a CommonJS script, rename it to use the '.cjs' file extension.
```

What does `__dirname` mean in Node? You may ask.

The `__dirname` global variable contains the path to the current module's directory.

The global variables `__dirname` and `__filename` only exist in CommonJS modules and aren't available in ES modules.

So if you've enabled ES modules in Node.js (via `"type": "module"` in `package.json`) or using ES modules through a module bundler like Webpack, you'll no longer have access to these global variables.

This error is one of the most common errors developers face when switching from CommonJS modules to ES modules.

The workaround is quite easy, though. Here's how it's done:

1. Get the module file URL from the `import.meta` object
2. Convert the URL to a path by `fileUrlToPath()`
3. Get the module's directory by using the `path.dirname()` method

```js
import { fileURLToPath } from 'url';
import path from 'path';

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
```

The `import.meta` object exposes context-specific metadata to a JavaScript module, including the module's URL.

Whenever you need the `__dirname` value, you'll have to repeat the above instructions. It's better to create a helper function.

## Create a helper function to emulate __dirname functionality

You can create a helper function, which you can call anytime you need the `__dirname` value.


```js
// utils.js
import path from 'path'
import { fileURLToPath } from 'url'

const getDirName = function (moduleUrl) {
    const filename = fileURLToPath(moduleUrl)
    return path.dirname(filename)
}

export {
    getDirName
}
```

And use it like so:

```js
// ModuleA.js
import { getDirName } from './libs/utils'

// Getting the dirname of moduleA.js
const dirName = getDirName(import.meta.url)

console.log(dirName)
// output: /home/dwd/sandbox/modules
```
Please note you'll have to provide the `import.meta.url` when calling the `getDirName` function; If you refer to it from inside the `lib.js` module, it'll return the `utils.js` directory name (`/home/dwd/sandbox/libs`).

I hope this guide was helpful.

Thanks for reading.

---

**❤️ You might like:**

- [Cannot find module error in Node.js (Fixed)](https://www.decodingweb.dev/cannot-find-module-error-in-node-js-fixed)
- [TypeError: map is not a function in JavaScript in JavaScript (Fixed)](https://www.decodingweb.dev/fix-map-is-not-a-function-error-in-javascript)
- [SyntaxError: Unexpected end of JSON input in JavaScript (Fixed)](https://www.decodingweb.dev/syntaxerror-unexpected-end-of-json-input-in-javascript)
- [How to fix "ReferenceError: document is not defined" in JavaScript](https://www.decodingweb.dev/how-to-solve-referenceerror-document-is-not-defined)