__filename or __dirname disappeared in NodeJs!


I have been using __dirname and __filename for a long time now in NodeJs files but today itself while working on a NodeJs project I discovered the following error.


Initially, I thought I must have made a spelling mistake in the usage. I double-checked and it was correct. Then I thought of trying it's friend __dirname and to my surprise, it was also not defined


What is going on here?

Well, ES Module is what's causing the issue here. Read this from NodeJS website itself.

No __filename or __dirname# These CommonJS variables are not available in ES modules.

I have recently started writing all my code in ES Modules since they are now fully supported in the LTS(NodeJs 14) version of NodeJS.

This seems very logical as ES Module specs don't define them and it brings the browser JavaScript and NodeJs Javascript closer.

What is the alternative?

Instead of __filename you can use import.meta.url. Logically they are same but actual results are slightly different. import.meta.url gives URL and __filename gives absolute path

__fileName: /Users/hariombalhara/www/test.js

import.meta.url: file:///Users/hariombalhara/www/test.js

new URL(import.meta.URL).pathname // This would be same as __filename

For a use case where you need to find the absolute path of a file relative to the current file's directory, see the following example comparing the two.

$ cat test.js                                                                                                                                      
  const path = require('path')
  console.log(path.join(__dirname, '../abc'))

$ node test.js                                                                                                                                     

$ cat test.mjs                                                                                                                                     
  import fs from 'fs'
  // Compute path relative to import.meta.url
  const u = new URL('../abc', import.meta.url).pathname

$ node test.mjs                                                                                                                                    
... Loading comments