How to fix “__dirname is not defined in ES module scope”
The situation
I encountered this error when I was migrating an old project from CommonJS to ES modules, and the entry file uses __dirname
which is a global variable. The error message looked like this:
By using __dirname
in a Node script, you can get the path of the directory housing the current JavaScript file, many Node.js applications use this global variable.
When used in a CommonJS module (when "type": "module"
is not defined in your application’s package.json
file), __dirname works without hassles, but, when used in an ES module, the error “__dirname is not defined in ES module scope” shows up.
The solution
I looked in the Node.js documentation for ES modules, specifically the import.meta
object. Also, since what we need is the name of the directory the current script/module is contained in, we can leverage Node.js’s path module. There is also a function in the url
module: fileURLToPath
, that returns a fully-resolved path to the file.
So, we need to import both the path module, as well as the the fileURLToPath
function from the url
module:
import path from 'path';
import { fileURLToPath } from 'url';
In order to replicate the functionality for the CommonJS’s __dirname, we just need to do the following:
const __filename = fileURLToPath(import.meta.url); // get the resolved path to the file
const __dirname = path.dirname(__filename); // get the name of the directory
Now, the __dirname
variable would work as it was in your script. To verify this in your script, you can just log it right after the definition:
console.log(__dirname);
There it is! I hope this helps you.