Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

__dirname is not defined #2907

Closed
mrddo-com opened this issue Aug 11, 2020 · 14 comments
Closed

__dirname is not defined #2907

mrddo-com opened this issue Aug 11, 2020 · 14 comments

Comments

@mrddo-com
Copy link

I wrote a simple program:

console.log('Hello world');
console.log(__dirname);

Error:

Hello world
file:///C:/prj/akb48teamsh/html/t.js:2
console.log(__dirname);
            ^

ReferenceError: __dirname is not defined
    at file:///C:/prj/akb48teamsh/html/t.js:2:13
    at ModuleJob.run (internal/modules/esm/module_job.js:140:23)
    at async Loader.import (internal/modules/esm/loader.js:165:24)
    at async Object.loadESM (internal/process/esm_loader.js:68:5)

The following version got error:
Node latest v14.7.0
Node LTS v12.8.2
Node LTS v12.8.3

But Node version v10.15.3 works fine.
Please help.

@lundibundi
Copy link
Member

As we can see from the stacktrace it looks like you are loading the file as a ECMAScript module (do you have "type": "module" in package.json?) which doesn't have __dirname or __filename, you can emulate those as explained in this documentation https://nodejs.org/api/esm.html#esm_no_require_exports_module_exports_filename_dirname.

@DerekNonGeneric DerekNonGeneric transferred this issue from nodejs/node Aug 11, 2020
@PoojaDurgad
Copy link

@mrddo-com - is this issue resolved? if yes can you close the issue please?

@mrddo-com
Copy link
Author

The issue seem to be fix in v14.13.0

@dcjayasuriya2020
Copy link

dcjayasuriya2020 commented Jan 10, 2021

this way it works:

import path from 'path';
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

1st get the __filename and then __dirname
both these CommonJs variables are not in ES modules, as per Node.org
we have to replicate with import.meta.url

Source:https://nodejs.org/api/esm.html#esm_no_require_exports_module_exports_filename_dirname

@corydorning
Copy link

The issue seem to be fix in v14.13.0

I'm using node v14.15.4 and this issue persists. The workaround from @lundibundi and @dcjayasuriya2020 does work though.

@blachawk
Copy link

blachawk commented Feb 11, 2021

I'm working off of node.js 14.15, and making use of import.meta.url as mentioned here by the node.js team.

  • I have my main app named as app.mjs within my root directory.
  • Within my package.json file I defined my start script as "start": "node app.mjs"
  • I then have the following configured in my app.mjs file...
import express from 'express';
import path from 'path';
import { fileURLToPath } from 'url';

const app = express();

//we need to change up how __dirname is used for ES6 purposes
const __dirname = path.dirname(fileURLToPath(import.meta.url));
//now please load my static html and css files for my express app, from my /dist directory
app.use(express.static(path.join(__dirname ,'dist')));

//works...

perhaps a little more than the question needed, but shows the process.

  • I didn't have to add type model to my package.json file
  • I didn't have to install any babel files
  • I didn't have to depend on any other npm packages, other than nodemon for server reloading purposes.

@Mustafa-Agha
Copy link

Mustafa-Agha commented Apr 17, 2021

I think we can create a global.__dirname = process.cwd();
This will get the directory where the process.cwd() is invoked

@addaleax
Copy link
Member

@dcjayasuriya2020’s answer is the right one. process.cwd() will not give you the right directory under most circumstances.

@p3k
Copy link

p3k commented Apr 28, 2021

As we can see from the stacktrace it looks like you are loading the file as a ECMAScript module (do you have "type": "module" in package.json?) which doesn't have __dirname or __filename, you can emulate those as explained in this documentation https://nodejs.org/api/esm.html#esm_no_require_exports_module_exports_filename_dirname.

the url is now leading to the latest docs where the corresponding section has been removed. this is the url i found:

https://nodejs.org/docs/latest-v12.x/api/esm.html#esm_no_require_exports_module_exports_filename_dirname

@tchetwin
Copy link

tchetwin commented Jun 1, 2021

The docs have updated slightly, the new location is https://nodejs.org/api/esm.html#esm_no_filename_or_dirname

@zlogg
Copy link

zlogg commented Jun 4, 2021

Uncaught ReferenceError: __dirname is not defined

@jhunterkohler
Copy link

@sunmar25 The __dirname and __filename globals are not defined in esm modules. To get the path do one of the following:

Method 1: URL (global)

function dirname(meta) {
    return new URL("", meta.url).pathname;
}

// call with import.meta
const __dirname = dirname(import.meta);

Method 2: fileURLToPath (requires an import)

import { fileURLToPath } from "url"; // the node package 'url'

function dirname(meta) {
    return fileURLToPath(meta.url);
}

// call with import.meta
const __dirname = dirname(import.meta);

Do not use process.cwd(). This fetches the current working directory, which will be the call location of the project, and thus inaccurate for other files. You have to pass import.meta to a function because import.meta varies values over files.

Use Globally

If you want this globally, add it to the Node.js global object like such:

Object.defineProperty(global, "dirname", dirname) // where dirname is one of the two functions above

@fnpen
Copy link

fnpen commented Jun 11, 2021

You can use it in head of entry:


import { fileURLToPath } from 'url';

Object.defineProperty(global, '__dirname', {
	__proto__: null,
	get: () => fileURLToPath(import.meta.url),
});

@addaleax
Copy link
Member

Method 1: URL (global)

Do not do this. new URL(...).pathname may contain percent-encoded characters, which do not match the actual file path in that case.

You can use it in head of entry:

Do not do this. The point of __dirname is that it has different values in different scripts. Defining it on the global object has the exact opposite effect.

I’ll lock this thread – @dcjayasuriya2020’s answer is the right one, for everybody who comes looking: #2907 (comment). If you have another question, open a new ticket.

@nodejs nodejs locked as resolved and limited conversation to collaborators Jun 11, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests