¿Cómo puedo importar el paquete node-fetch a mi proyecto de nodo donde uso typescript ? Lo probé de muchas maneras... ahora mismo estoy en:
const fetch = (...args) => import("node-fetch").then(({ default: fetch }) => fetch(...args));Pero tengo 2 errores:
Cannot redeclare block-scoped variable 'fetch'.y
A spread argument must either have a tuple type or be passed to a rest parameter. Cuando cambio const fetch = a cualquier otro nombre como const fetchIt = corrige el primer error pero... ¿realmente tengo que cambiar eso? ¿Cómo puedo importar el paquete node-fetch de manera normal donde puedo usar el método fetch() ? En React solo hago
import fetch from 'node-fetch'; y todo funciona bien... ¿por qué es tan difícil en los proyectos de node ?
Si tiene conflictos con una fetch global, esto sugiere que tiene habilitado DOM lib en su tsconfig.json , por ejemplo:
{ "compilerOptions": { "lib": ["es2021", "dom"] } } Sugeriría eliminar esto. Para un proyecto de NodeJS, eche un vistazo a esta respuesta para conocer la configuración sugerida de tsconfig.json según la versión de NodeJS.
Después de esto, podrá importar fetch como escribió en su pregunta y asignarlo a una variable llamada fetch , sin nombres en conflicto:
import fetch from 'node-fetch'; Solución alternativa: si necesita trabajar con bibliotecas de terceros que se construyen con un enfoque de navegador y requieren una recuperación global, eche un vistazo al módulo isomorphic-fetch , que agrega la función de fetch como global.
Deberá importarlo una vez para que fetch esté disponible globalmente:
import 'isomorphic-fetch'; En este caso, las opciones del compilador de su tsconfig.json deben contener dom lib.
Las versiones más nuevas de NodeJS ahora incluyen una API de fetch nativa, por lo que lo anterior ya no será necesario en el futuro. Ver aquí y aquí para más información.
Mi publicación original a continuación es toda cierta. Sin embargo, pude hacerlo funcionar sin tener que cambiar a los módulos ESM. Esto es lo que funciona en mi código (basado en el tercer fragmento de código en la siguiente publicación: 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); }; El error Cannot redeclare block-scoped variable 'fetch' se debe a que está declarando una variable de const fetch y luego reutilizando el nombre " fetch " como el parámetro desestructurado del objeto para la devolución de llamada then() más adelante en la línea.
Entonces, cambiar la línea para que lea de la siguiente manera aclara ese error:
const fetch = (...args) => import("node-fetch").then(module => module.default(...args)); En cuanto al otro error ( A spread argument must either have a tuple type or be passed to a rest parameter. ), una forma posible de resolver esto sería importar los tipos de argumento correctos para la llamada fetch() , luego sustituir en el fragmento de código anterior según corresponda, así:
import { RequestInfo, RequestInit } from 'node-fetch'; const fetch = (url:RequestInfo, init?:RequestInit) => import('node-fetch').then(module => module.default(url, init)); Desafortunadamente, aunque eso parece satisfacer al compilador de TypeScript, encuentro en mi propio código que el tiempo de ejecución aún no funciona (arroja un ERR_REQUIRE_ESM ) porque mi configuración de TypeScript actualmente usa módulos CommonJS en lugar de un formato ESM.
Consulte https://github.com/node-fetch/node-fetch/issues?q=ERR_REQUIRE_ESM para conocer varios problemas abiertos en el paquete de búsqueda de nodos relacionados con este problema.
Esencialmente, los mantenedores de búsqueda de nodos sugieren que aquellos de nosotros que usamos TypeScript necesitamos convertir a módulos ESM, lejos de CommonJS (ver https://github.com/node-fetch/node-fetch/issues/1397#issuecomment-978092116 y comentarios posteriores).