I encountered the ReferenceError: _dirname is not defined in ES module scope while migrating an old project from CommonJS to ES modules. The entry file used __dirname, which is a global variable, and the error message looked like this:
This is a common error that indicates you’re trying to use the __dirname variable in an ES module (type: “module” in package.json or using .mjs extension), but __dirname is only available in CommonJS by default.
ReferenceError: “__dirname Is Not defined in ES Module Scope”
- Import the path module and
fileURLtoPathfrom theURLmodule.:import path from 'path'; import { fileURLToPath } from 'url'; - Replicate the functionality of the CommonJS
__dirnamevariable:const __filename = fileURLToPath(import.meta.url); // get the resolved path to the file const __dirname = path.dirname(__filename); // get the name of the directory - Verify that the
__dirnamevariable works in your script:console.log(__dirname);
What Causes the ‘__dirname Is Not Defined in ES Module Scope’?
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 hassle, but when used in an ES module, the error __dirname is not defined in ES module scope shows up.
How to Resolve ‘__dirname Is Not Defined in ES Module Scope’
First, I reviewed the import.meta object documentation for ES modules. Since what we need is the name of the directory the current script/module is contained in, we can leverage Node.js’ 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 and the fileURLToPath function from the url module:
import path from 'path';
import { fileURLToPath } from 'url';
In order to replicate the functionality for the CommonJS’ __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
The code above retrieves the full path of the current ES module file using fileURLToPath(import.meta.url), and then extracts the directory name of that file using path.dirname(), effectively replicating the __dirname behavior in CommonJS for ES modules.
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.
Frequently Asked Questions
What causes the “ReferenceError: __dirname is not defined in es module scope”?
The ReferenceError: __dirname is not defined in ES module scope occurs because __dirname is a CommonJS-specific global and is not available in ECMAScript modules (ESM) by default.
How do you solve the “ReferenceError: __dirname is not defined in es module scope”?
- Import the path module and
fileURLtoPathfrom theURLmodule.import path from 'path'; import { fileURLToPath } from 'url'; - Replicate the functionality of the CommonJS __dirname variable.
const __filename = fileURLToPath(import.meta.url); // get the resolved path to the file const __dirname = path.dirname(__filename); // get the name of the directory - Verify in your script.
console.log(__dirname);
