10

I need to calculate a pathname relative to the file-system location of the module. I am using the latest TypeScript on Node.js 12.x. For other reasons in tsconfig.json I have set

        "target": "esnext",
        "module": "esnext",

This triggers a mode that is strict to the Node.js support for ES6 Modules. In that mode the __dirname variable is not available because that global is not defined in the ECMAScript spec. What we're supposed to do instead is access the import.meta.url variable and extract the directory name.

For an example see the last answer on this question: Alternative for __dirname in Node.js when using ES6 modules

But in the TypeScript DefinitelyTyped collection the ImportMeta class is not defined to include a url member. Therefore the code fails to compile:

tdn.ts:7:25 - error TS2339: Property 'url' does not exist on type 'ImportMeta'.

7 console.log(import.meta.url);
                          ~~~

I wasn't able to find the definition of ImportMeta in the Definitely Typed repository. But it seems to be improperly defined. In node_modules/typescript/lib/lib.es5.d.ts I found this:

/**
 * The type of `import.meta`.
 *
 * If you need to declare that a given property exists on `import.meta`,
 * this type may be augmented via interface merging.
 */
interface ImportMeta {
}

In the Node.js 12.x documentation on the ES Modules page it clearly describes the shape of import.meta and that we're supposed to do something like:

import path from 'path';
import { fileURLToPath } from 'url';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

3 Answers 3

9

'__dirname', '__filename' and 'require'...etc are NodeJS specific keywords, and by default typescript doesn't recognize them, although you need to know that the compiler compile the ts file to js file (by default) and it works fine, in order to clear the errors you can to run this on your terminal (or cmd on windows):

npm install --save-dev @types/node

that would install nodejs types definitions and allow you to avoid this type of errors when writing your nodejs programs in typescript.

Sign up to request clarification or add additional context in comments.

1 Comment

besides, you also need to add to tsconfig.json: compilerOptions.types: ['node']
6

using import.meta and fileToURLupdate this works...

As per NODE.org, both CommonJs variables specially __dirname or __filename are not available in ES Modules. We have to replicate those commonJs variables from via import.meta.url. Source: https://nodejs.org/api/esm.html#esm_no_filename_or_dirname

Comments

0

As of today this can be done with this (somewhat clumsy) statement:

import { fileURLToPath } from 'url';
import { dirname } from 'path';

const __dirname = dirname(fileURLToPath(import.meta.url));

This will work without errors on a supported Node with updated types.

On a very recent Node (at least 24.x or later versions of 22.x), you can also use the more succinct:

const __dirname = import.meta.dirname;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.