Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Equivalent for __dirname in TypeScript when using target/module=esnext

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);
like image 291
David Herron Avatar asked Apr 22 '26 09:04

David Herron


2 Answers

'__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.

like image 176
Hocine Abdellatif Houari Avatar answered Apr 24 '26 22:04

Hocine Abdellatif Houari


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

like image 22
DilshanChelaka Jayasuriya Avatar answered Apr 25 '26 00:04

DilshanChelaka Jayasuriya



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!