关于node.js:使用target / module = esnext时等同于TypeScript中的__dirname

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

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

1
2
       "target":"esnext",
       "module":"esnext",

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

有关示例,请参见此问题的最后答案:使用--experimental-modules标志时,节点中__dirname的替代方法

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

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

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

我在"绝对类型"存储库中找不到ImportMeta的定义。但这似乎定义不正确。

更新:在node_modules//typescript/lib/lib.es5.d.ts中,我发现了这一点:

1
2
3
4
5
6
7
8
/**
 * 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 {
}

啊...

/更新

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

1
2
3
4
5
import path from 'path';
import { fileURLToPath } from 'url';

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

'__dirname','__ filename'和'require'... etc是NodeJS特定的关键字,尽管您需要知道编译器将ts文件编译为js文件(默认情况下),但默认情况下typescript不能识别它们。 它工作正常,为了清除错误,您可以在终端(或Windows上的cmd)上运行此命令:

1
npm install --save @types/node

这将安装nodejs类型定义,并允许您在打字稿中编写nodejs程序时避免此类错误。