The “__dirname is not defined in ES module scope” error happens in JavaScript when we try to access the __dirname
global variable in an ES module. The __dirname
and __filename
global variables are defined in CommonJS modules, but not in ES modules.
We can fix the “__dirname is not defined in ES module scope” error by using certain functions to create a custom __dirname
variable that works just like the global variable, containing the full path of the file’s current working directly.
index.js
import path from 'path';
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
// C:/cb/cb-js
console.log(__dirname);
// C:\cb\cb-js\index.html
console.log(path.join(__dirname, 'index.html'));
The import.meta
object contains context-specific metadata associated with a certain module, e.g., a module’s file URL.
// file:///C:/cb/cb-js/index.js
console.log(import.meta.url);
So we get the current module’s file URL and pass it to the fileURLToPath
function from the url
module, to convert it to a file path. fileURLToPath
returns a fully-resolved, platform-specific Node.js file path.
// C:\cb\cb-js\index.js
console.log(fileURLToPath('file:///C:/cb/cb-js/index.js'));
After getting the file path, we pass it to the dirname
method from the path
module, to get the full directory path from the file path.
// C:\cb\cb-js
console.log(path.dirname('C:\\cb\\cb-js\\index.js'));
With this, we now have our own __dirname
and __filename
variables.
Here’s the output from logging them from a file on my computer.
__filename
contains the absolute path of the current module file.
__dirname
contains the absolute path of the current module file’s directory.
Create utility for __dirname
and __filename
If we access the __dirname
and __filename
variables frequently, we can abstract the logic for creating them in a utility module and avoid unnecessary repetition.
file-dir-name.js
import { fileURLToPath } from 'url';
import { dirname } from 'path';
export default function fileDirName(meta) {
const __filename = fileURLToPath(meta.url);
const __dirname = dirname(__filename);
return { __dirname, __filename };
}
We’ll be able to use this utility across the various other module files in our project.
index.js
import fileDirName from './file-dir-name.js';
const { __dirname, __filename } = fileDirName(import.meta);
// C:\cb\cb-js
console.log(__dirname);
// C:\cb\cb-js\index.js
console.log(__filename);
11 Amazing New JavaScript Features in ES13
This guide will bring you up to speed with all the latest features added in ECMAScript 13. These powerful new features will modernize your JavaScript with shorter and more expressive code.