使用 target/module=esnext 时相当于 TypeScript 中的 __dirname

Dav*_*ron 6 node.js typescript

我需要计算相对于模块的文件系统位置的路径名。我在 Node.js 12.x 上使用最新的 TypeScript。由于其他原因,tsconfig.json我已设置

        "target": "esnext",
        "module": "esnext",
Run Code Online (Sandbox Code Playgroud)

这会触发一种严格限制 Node.js 对 ES6 模块支持的模式。在该模式下,__dirname变量不可用,因为 ESanything 规范中未定义该全局变量。我们应该做的是访问import.meta.url变量并提取目录名称。

例如,请参阅此问题的最后一个答案:Alternative for __dirname in node when using the --experimental-modules flag

但在 TypeScript DefinedTyped 集合中,ImportMeta 类未定义为包含成员url。因此代码无法编译:

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

7 console.log(import.meta.url);
                          ~~~
Run Code Online (Sandbox Code Playgroud)

我无法在 Definely Typed 存储库中找到 ImportMeta 的定义。但它的定义似乎不恰当。

更新:在node_modules//typescript/lib/lib.es5.d.ts我发现这个:

/**
 * 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 {
}
Run Code Online (Sandbox Code Playgroud)

啊...

/更新

在 ES 模块页面上的 Node.js 12.x 文档中,它清楚地描述了import.meta我们应该做的事情,例如:

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

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
Run Code Online (Sandbox Code Playgroud)

Hoc*_*tif 3

'__dirname'、'__filename' 和 'require'...等是 NodeJS 特定的关键字,默认情况下 typescript 无法识别它们,尽管您需要知道编译器将 ts 文件编译为 js 文件(默认情况下)并且它工作正常,为了清除错误,您可以在终端(或 Windows 上的 cmd)上运行它:

npm install --save @types/node
Run Code Online (Sandbox Code Playgroud)

这将安装 NodeJS 类型定义,并允许您在使用 TypeScript 编写 NodeJS 程序时避免此类错误。