How to fix “__dirname is not defined in ES module scope”
The error “__dirname is not defined in ES module scope” occurs if you refer to the __dirname
global variable in an ES (ECMAScript) module.
🎧 Debugging Jam
Calling all coders in need of a rhythm boost! Tune in to our 24/7 Lofi Coding Radio on YouTube, and let's code to the beat – subscribe for the ultimate coding groove!" Let the bug-hunting begin! 🎵💻🚀
Here’s what the error message looks like:
file:///home/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.
This global variable contains the path to the current module's directory.
Psssst! Do you want to learn web development in 2023?
The __dirname
and __filename
variables 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 ES module scope error is one of the most common errors developers face when switching from CommonJS modules to ES modules.
The workaround is quite easy, though.
To get a module's directory path in the ES module system:
- First, get the module file URL from the
import.meta
object. - Then, convert the URL to a path by the
fileUrlToPath()
function. - Finally, 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 = path.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 in your app
You can create a helper function, which you can call anytime you need the __dirname
value.
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:
// 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
whenever calling the function; If you refer to it from inside the lib.js
module, it'll return the utils.js
directory name (/home/dwd/sandbox/libs
) instead.
I hope this quick guide was helpful.
Thanks for reading.
Never miss a guide like this!
Disclaimer: This post may contain affiliate links. I might receive a commission if a purchase is made. However, it doesn’t change the cost you’ll pay.