【问题标题】:Importing node-fetch in node project with typescript使用打字稿在节点项目中导入节点获取
【发布时间】:2022-01-05 13:50:02
【问题描述】:

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

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

但我有 2 个错误:

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 项目中这么难?

【问题讨论】:

  • 您是否在您的tsconfig.json 中启用了DOM 库?如果您删除它,则与全局 fetch 不应该有任何冲突。
  • @qqilihq 我刚刚执行了npx tsc --init 命令,所以我在那里拥有所有默认值,但我认为那里没有看到任何DOM

标签: javascript node.js typescript fetch


【解决方案1】:

更新:

我下面的原始帖子都是真实的。然而,我已经能够让它工作,而无需切换到 ESM 模块。这是我的代码中的工作内容(基于以下帖子中的第三个代码 sn-p: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()调用实际导入正确的参数类型,然后根据需要替换上面的代码sn-p,像这样:

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格式。

请参阅https://github.com/node-fetch/node-fetch/issues?q=ERR_REQUIRE_ESM,了解与此问题相关的 node-fetch 包中的几个未解决问题。

基本上,node-fetch 维护者建议我们这些使用 TypeScript 的人需要转换为 ESM 模块,远离 CommonJS(请参阅 https://github.com/node-fetch/node-fetch/issues/1397#issuecomment-978092116 和后续的 cmets)。

【讨论】:

    【解决方案2】:

    如果您与全局 fetch 发生冲突,这表明您已启用 tsconfig.json 中的 DOM 库,例如:

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

    我建议删除这个。对于 NodeJS 项目,请查看 this 答案以获取建议的 tsconfig.json 设置,具体取决于 NodeJS 版本。

    在此之后,您将能够导入您在问题中所写的 fetch,并将其分配给名为 fetch 的变量,而不会出现名称冲突:

    import fetch from 'node-fetch';
    

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

    您需要将其导入一次,以便 fetch 在全球范围内可用:

    import 'isomorphic-fetch';
    

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

    【讨论】:

      猜你喜欢
      • 2013-02-25
      • 2021-12-25
      • 2022-01-14
      • 1970-01-01
      • 1970-01-01
      • 2022-08-18
      • 2017-02-21
      • 2021-12-05
      • 1970-01-01
      相关资源
      最近更新 更多