使用target / module = esnext

时间:2019-05-06 03:20:00

标签: node.js typescript

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

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

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

有关示例,请参见此问题的最后答案:Alternative for __dirname in node when using the --experimental-modules flag

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

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中,我发现了这一点:

/**
 * 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 {
}

gh ...

/ UPDATE

在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);

2 个答案:

答案 0 :(得分:3)

使用 import.metafileToURLupdate 这有效...

根据 NODE.org,两个 CommonJs 变量,特别是 __dirname 或 __filename 在 ES 模块中都不可用。 我们必须通过 import.meta.url 复制那些 commonJs 变量。 来源:https://nodejs.org/api/esm.html#esm_no_filename_or_dirname

答案 1 :(得分:1)

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

let views = document.createElement('p');
views.innerHTML = '<i class="fas fa-eye"></i>' + getViews(video);

...

const getViews = (video) => {
    const url = 'https://www.googleapis.com/youtube/v3/videos?part=contentDetails,statistics&id=' + video.id + '&key=' + api;
    // console.log(url);
    fetch(url).then((response) => {
        return response.json();
    }).then((data) => {
        console.log(data.items[0].statistics.viewCount); // it works here
        return data.items[0].statistics.viewCount; // but not here 
    }).catch((error) => {
        console.log(error);
    })
};

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