When transitioning from the CommonJS module system to ES modules, developers may encounter the “ReferenceError: __dirname is not defined in ES module scope” error.
Wherein modern JavaScript development, the adoption of ES modules has gained significant popularity due to their ability to organize and modularize code.
This error occurs when trying to access the __dirname variable within an ES module, which is not available by default.
In this article, we will explore the reasons behind this error and possible solutions.
What is Referenceerror: __dirname is not defined in es module scope?
The error message “ReferenceError:__dirname is not defined in ES module scope” occurs when attempting to utilize the __dirname global variable within an ES module file.
In ECMAScript module files, the __dirname or __filename global variables are inaccessible.
Here’s an example program that can trigger the “ReferenceError: __dirname is not defined in ES module scope” error:
// index.js
console.log(__dirname);
In this example, we have a simple index.js file that attempts to log the value of __dirname to the console.
However, if you try to run this file as an ECMAScript module using a tool like Node.js with the –experimental-modules flag, you will encounter the mentioned error:
(node:1234) ExperimentalWarning: The ESM module loader is experimental.
internal/modules/run_main.js:54
internalBinding('errors').triggerUncaughtException(
^
ReferenceError: __dirname is not defined in ES module scope
at file:///path/to/index.js:2:13
at ModuleJob.run (internal/modules/esm/module_job.js:183:25)
at async Loader.import (internal/modules/esm/loader.js:178:24)
at async Object.loadESM (internal/process/esm_loader.js:68:5)
The error occurs because when running a file as an ECMAScript module, the __dirname variable is not defined within the module’s scope.
Solutions – Referenceerror: __dirname is not defined in es module scope
Certainly! Here are the solutions to fix the “ReferenceError: dirname is not defined in ES module scope” error along with their examples.
Solution 1. Convert the file to a CommonJS module
First, we need to change the file extension from .js to .mjs to indicate that it’s a CommonJS module.
Then we will update the import/export syntax to be compatible with CommonJS.
Here is an example:
// index.mjs
import path from 'path';
console.log(path.dirname(new URL(import.meta.url).pathname));
In this particular instance, we utilize the import.meta.url property to obtain the URL of the current file, and subsequently extract the directory path by employing the path.dirname function from the Node.js path module.
Solution 2. Use a different approach
Alternatively, we utilize the import.meta.url property to get the URL of the current file.
This will extract the directory path using a combination of URL and path manipulation.
Here’s an example:
// index.js
import { fileURLToPath } from 'url';
import path from 'path';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
console.log(__dirname);
In this example, we use the fileURLToPath function from the built-in url module to convert the import.meta.url into a file path.
Then, we use the path.dirname function from the path module to extract the directory path.
Solution 3. Use a bundler
In this case, if you are engaged in a more extensive project, employing a bundler such as Webpack or Rollup proves beneficial.
These tools manage module resolution and offer assistance for variables like __dirname in your codebase.
Here’s an illustration demonstrating the usage of Webpack:
First Install the required dependencies:
npm install webpack webpack-cli
Then create a webpack.config.js file:
// webpack.config.js
const path = require('path');
module.exports = {
mode: 'development',
entry: './index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
},
};
After which, Modify the index.js file:
// index.js
console.log(__dirname);
Finally, run the Webpack bundling process.
npx webpack
Webpack will bundle your code and handle the module resolution, allowing you to use __dirname without encountering any errors.
Note: The configuration provided here assumes a basic setup. You may need to adjust it based on your project’s requirements.
By following any of these solutions, you should be able to resolve the “ReferenceError: __dirname is not defined in ES module scope” error.
Anyway besides this error, we also have fixed errors that you can check which might help you when you encounter them.
- Referenceerror: response is not defined
- Reference error: navigator is not defined
- Referenceerror request is not defined
Conclusion
In summary, the error ReferenceError: dirname is not defined in ES module scope arises due to the difference in the handling of module scopes between ECMAScript modules and CommonJS modules.
Understanding the available solutions allows you to address the error and continue working with your code effectively.
I think that’s all for this error. We hope this article has helped fix the issues.
Until next time! 😊
let / const / var scope ReferenceError patterns
JavaScript ReferenceError often comes from accessing variables outside their scope. let and const are block-scoped (visible only inside the enclosing curly braces); var is function-scoped and hoisted.
Common triggers
- let / const outside block. Declared inside
iforforblock — invisible outside. - Temporal dead zone. Accessing
let/constbefore declaration in the same scope raises ReferenceError. - Function expression before declaration.
const fn = () => ...is not hoisted; using fn earlier fails. - Typo in variable name. Case-sensitive —
userNamevsusername. - Missing var/let/const declaration. In strict mode, assigning to undeclared variables raises ReferenceError.
Diagnostic pattern
// BAD — let outside block
if (isValid) {
let result = compute();
}
console.log(result); // ReferenceError: result is not defined
// GOOD — declare in outer scope
let result;
if (isValid) {
result = compute();
}
console.log(result);
// BAD — temporal dead zone
console.log(x); // ReferenceError
const x = 5;
// GOOD — declare before use
const x = 5;
console.log(x);
Best practices
- Prefer const, use let when reassigning. Avoid var entirely in modern JS.
- Use “use strict” or ES modules. Strict mode raises ReferenceError on undeclared assignments.
- Enable ESLint no-undef and no-use-before-define rules.
- Use TypeScript. All scope issues caught at compile time.
Official documentation
Frequently Asked Questions
What is JavaScript ReferenceError and what causes it?
ReferenceError is raised when JavaScript tries to use a variable that doesn’t exist in the current scope. Common causes: typo in variable name, accessing a variable declared with let/const before its declaration (temporal dead zone), assuming Node.js globals exist in the browser (or vice versa), or import path errors in ES modules.
How do I fix ‘window is not defined’ in Next.js or SSR?
Server-side rendering runs your code on the server where ‘window’ (a browser-only global) doesn’t exist. Fix: gate the code with typeof window !== ‘undefined’ OR move it into a useEffect (which only runs client-side). For Next.js, dynamic import with ssr: false also works.
How do I fix ‘fetch is not defined’ in Node.js?
fetch was browser-only until Node 18. Three fixes: (1) Upgrade to Node 18+. (2) Install node-fetch (npm install node-fetch) and import it. (3) Use axios as a cross-platform alternative. For React Native, use the built-in fetch (it’s a browser-like environment).
What is the temporal dead zone in JavaScript?
The period between when a let/const variable is hoisted to the top of its block and when it’s actually declared. Accessing it during this window throws ReferenceError. Example: console.log(x); let x = 5; throws because x hasn’t been declared yet. With var, this would print undefined instead (var is hoisted with undefined value).
Where can I find more ReferenceError fixes?
Browse the ReferenceError reference hub for 34+ specific JavaScript fixes (Node ESM, SSR, React, browser globals). For JavaScript fundamentals see the JavaScript Tutorial hub.
