DEV Community

Cover image for About “__dirname is not defined in ES module scope” in JavaScript
Reza Lavarian
Reza Lavarian

Posted on • Originally published at decodingweb.dev

2

About “__dirname is not defined in ES module scope” in JavaScript

Update: This post was originally published on my blog decodingweb.dev, where you can read the latest version 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.
Enter fullscreen mode Exit fullscreen mode

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
import { fileURLToPath } from 'url';
import path from 'path';

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
Enter fullscreen mode Exit fullscreen mode

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.

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

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

export {
    getDirName
}
Enter fullscreen mode Exit fullscreen mode

And use it like so:

// 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
Enter fullscreen mode Exit fullscreen mode

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:

Sentry blog image

How I fixed 20 seconds of lag for every user in just 20 minutes.

Our AI agent was running 10-20 seconds slower than it should, impacting both our own developers and our early adopters. See how I used Sentry Profiling to fix it in record time.

Read more

Top comments (1)

Collapse
 
naucode profile image
Al - Naucode

Great article, you got my follow, keep writing!

Cloudinary image

Video API: manage, encode, and optimize for any device, channel or network condition. Deliver branded video experiences in minutes and get deep engagement insights.

Learn more

AWS GenAI LIVE!

GenAI LIVE! is a dynamic live-streamed show exploring how AWS and our partners are helping organizations unlock real value with generative AI.

Tune in to the full event

DEV is partnering to bring live events to the community. Join us or dismiss this billboard if you're not interested. ❤️