2

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 ESanything 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 when using the --experimental-modules flag

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.

UPDATE: 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 {
}

Ugh...

/UPDATE

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);
David Herron
  • 538
  • 7
  • 17

2 Answers2

3

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

leonheess
  • 5,825
  • 6
  • 42
  • 67
1

'__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 @types/node

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