使用typescript在节点项目中导入取节点

kzmpq1sx  于 2023-01-14  发布在  TypeScript
关注(0)|答案(4)|浏览(155)

如何将node-fetch包导入到我使用typescript的节点项目中。我尝试了很多方法...现在我在:

const fetch = (...args) =>
    import("node-fetch").then(({ default: fetch }) => fetch(...args));

但我有两个错误:

Cannot redeclare block-scoped variable 'fetch'.

以及

A spread argument must either have a tuple type or be passed to a rest parameter.

当我将const fetch =更改为任何其他名称(如const fetchIt =)时,它修复了第一个错误,但是...我真的必须更改它吗?我如何以正常方式导入node-fetch包,在那里我可以使用fetch()方法?在React中,我只需要

import fetch from 'node-fetch';

而且一切都很好...为什么在node项目中这么难呢?

u5rb5r59

u5rb5r591#

如果您与全局fetch有冲突,则建议您启用tsconfig.json中的DOM库,例如:

{
  "compilerOptions": {
    "lib": ["es2021", "dom"]
  }
}

我建议删除这个。对于NodeJS项目,根据NodeJS版本,查看this对建议的tsconfig.json设置的回答。
在此之后,您将能够按照您在问题中所写的那样导入fetch,并将其赋值给名为fetch的变量,而不会出现名称冲突:

import fetch from 'node-fetch';

**替代解决方案:**如果您需要使用以浏览器为中心构建的第三方库,并且需要全局获取,请查看isomorphic-fetch模块,该模块添加了fetch作为全局函数。

您需要导入一次,以便fetch在全局可用:

import 'isomorphic-fetch';

在这种情况下,tsconfig.json的编译器选项应该包含dom库。

更新日期:2022年2月4日

新的NodeJS版本现在提供了一个原生的fetch API,因此以后不再需要上面的API。更多信息请参见herehere

shyt4zoc

shyt4zoc2#

更新:

我下面的原始帖子都是真的。不过,我已经能够让它工作了,而不必切换到ESM模块。下面是我的代码中的工作原理(基于下面帖子中的第三个代码片段:https://github.com/node-fetch/node-fetch/issues/1279#issuecomment-915063354)

// eslint-disable-next-line no-new-func
const importDynamic = new Function('modulePath', 'return import(modulePath)');

const fetch = async (...args:any[]) => {
  const module = await importDynamic('node-fetch');
  return module.default(...args);
};

原始帖子:

Cannot redeclare block-scoped variable 'fetch'错误是因为您声明了一个const fetch变量,然后重用名称"fetch"作为then()回调的对象反结构化参数。
因此,将该行更改为如下形式可清除该错误:

const fetch = (...args) => import("node-fetch").then(module => module.default(...args));

至于另一个错误(A spread argument must either have a tuple type or be passed to a rest parameter.),解决这个问题的一种可能方法是为fetch()调用导入正确的参数类型,然后根据需要替换为上面的代码片段,如下所示:

import { RequestInfo, RequestInit } from 'node-fetch';
const fetch = (url:RequestInfo, init?:RequestInit) => import('node-fetch').then(module => module.default(url, init));

不幸的是,虽然这似乎满足了TypeScript编译器,但我在自己的代码中发现运行时仍然不工作(抛出ERR_REQUIRE_ESM),因为我的TypeScript配置当前使用的是CommonJS模块,而不是ESM格式。
有关node-fetch包中与此问题相关的几个未决问题,请参见https://github.com/node-fetch/node-fetch/issues?q=ERR_REQUIRE_ESM
本质上,节点获取维护者建议我们这些使用TypeScript的人需要转换到ESM模块,远离CommonJS(参见www.example.com和后续评论)。https://github.com/node-fetch/node-fetch/issues/1397#issuecomment-978092116 and subsequent comments).

qfe3c7zg

qfe3c7zg3#

降级或安装v2. npm install node-fetch@2 && npm install --save-dev @types/node-fetch@2.x😡
当node不支持ESM 3.x时,ESM 3.x有什么意义呢?至少对tsc是这样。也许ts-node支持它。但是tsc应该与ts-node兼容。

import { default as fetch, Headers } from 'node-fetch';

配置

{
    "$schema": "https://json.schemastore.org/tsconfig",
    "display": "Node 12",
    "compilerOptions": {
      "lib": ["es2019"],
      "module": "commonjs",
      "target": "es2019",
      "strict": true,
      "esModuleInterop": true,
      "skipLibCheck": true,
      "forceConsistentCasingInFileNames": true,
      "moduleResolution": "node"
    },
    "include": [
        "**/*.ts"
    ]
  }

注:节点14,将tsconfig从上述es 2019更新为es 2020并显示节点14
此外,Node 17+ fetch是内置的,因此当ESM在node中得到支持时,您可能不需要node-fetch。

yacmzcpb

yacmzcpb4#

我建议使用cross-fetch,它几乎是相同的,但在任何地方都适用,它帮助了我,因为我无法在TypeScript中运行节点获取

相关问题