[英]Importing node-fetch in node project with typescript
如何將node-fetch
package 導入我使用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 =
之類的任何其他名稱時,它修復了第一個錯誤但是......我真的必須改變它嗎? 如何在可以使用fetch()
方法的情況下以正常方式導入node-fetch
package? 在 React 中我只是做
import fetch from 'node-fetch';
一切正常......為什么在node
項目中如此困難?
如果您與全局fetch
發生沖突,這表明您在tsconfig.json
中啟用了DOM
庫,例如:
{
"compilerOptions": {
"lib": ["es2021", "dom"]
}
}
我建議刪除它。 對於 NodeJS 項目,根據 NodeJS 版本查看建議的tsconfig.json
設置的答案。
在此之后,您將能夠按照您在問題中所寫的方式導入fetch
並將其分配給名為fetch
的變量,而不會出現名稱沖突:
import fetch from 'node-fetch';
替代解決方案:如果您需要使用以瀏覽器為重點並需要全局提取的第 3 方庫,請查看isomorphic-fetch
模塊,該模塊將fetch
添加為全局 function。
您將需要導入一次,以便fetch
在全球范圍內可用:
import 'isomorphic-fetch';
在這種情況下,您的tsconfig.json
的編譯器選項應該包含dom
庫。
我下面的原始帖子都是真的。 然而,我已經能夠讓它工作,而無需切換到 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
變量,然后在該行后面的then()
回調中重用名稱“ fetch
”作為對象解構參數。
因此,將行更改為如下所示可以清除該錯誤:
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 格式。
有關與此問題相關的節點獲取 package 中的幾個未解決問題,請參閱https://github.com/node-fetch/node-fetch/issues?q=ERR_REQUIRE_ESM 。
本質上,node-fetch 維護者建議我們這些使用 TypeScript 的人需要轉換為 ESM 模塊,遠離 CommonJS(參見https://github.com/node-fetch/node-fetch/issues/1397#issuecomment-97809216和后續評論)。
降級或安裝 v2。 npm install node-fetch@2 && npm install --save-dev @types/node-fetch@2.x
當節點不支持 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 從上面的 es2019 更新為 es2020 & 顯示節點 14
我建議使用cross-fetch ,它幾乎相同,但在任何地方都可以使用,它對我有幫助,因為我無法在 TypeScript 中運行 node-fetch
這個設置對我有用:
package.json
{
"main": "index.ts",
"scripts": {
"start": "ts-node --esm ./src/index.ts"
},
"type": "module",
"dependencies": {
"@types/node": "^18.11.18",
"@types/node-fetch": "^2.6.2",
"node-fetch": "^3.3.0",
"nodemon": "^2.0.20",
"ts-node": "^10.9.1",
"typescript": "^4.9.5"
}
}
tsconfig.json
{
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"lib": ["ES2022", "DOM"],
"module": "ES2022",
"moduleResolution": "node",
"target": "ES2022",
"esModuleInterop": true,
}
}
索引.ts
import fetch, { Headers } from 'node-fetch';
// do something
我使用的是 ts-node,所以請注意您需要應用--esm
兼容性:
ts-node --esm./src/index.ts
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.