Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remix V1 to V2: Module '"@remix-run/node"' has no exported member 'fetch'.ts(2305) #7567

Closed
1 task done
cliffordfajardo opened this issue Oct 2, 2023 · 8 comments
Closed
1 task done
Labels
bug:unverified feat:fetch Issues related to @remix-run/web-fetch feat:typescript

Comments

@cliffordfajardo
Copy link
Contributor

cliffordfajardo commented Oct 2, 2023

What version of Remix are you using?

2.0.1

Are all your remix dependencies & dev-dependencies using the same version?

  • Yes

Steps to Reproduce

Was starting to upgrade to Remix V2, then I started seeing this error message in my app:

import { fetch } from "@remix-run/node"; // ❌Module '"@remix-run/node"' has no exported member 'fetch'.ts(2305)

import { Response } from "@remix-run/node"; // ❌Module '"@remix-run/node"' has no exported member 'Response

I know this is because fetch export was removed the @remix-run/node package per this PR #7293

Question

Is the only way to reliably get proper fetch typing for fetch on the server/nodejs to import it?

installGlobals doesn't help because when I COMMAND + CLICK into fetch implementation, I am taken to this type definition file located here:

/Applications/Visual Studio Code.app/Contents/Resources/app/extensions/node_modules/typescript/lib/lib.dom.d.ts

The browser implementation of fetch obviously doesnt have types for passing things like agent & other nodejs specif stuff to fetch's request options object.

For example, in my remix app, we need to pass a custom agent to our fetch

const response = await fetch(`example.com`, {
    method: "GET",
    headers: {
      "Content-type": "application/json",
    },
    agent: new https.Agent({ rejectUnauthorized: false, requestCert: false }), // <----🟡
  });
   return await response.json();
};
@cliffordfajardo
Copy link
Contributor Author

cliffordfajardo commented Oct 2, 2023

I think we should include fetch back into @remix-run/node 🤔

users won't need to go install node-fetch to be able to pass nodejs specific options (ex: agent) to the fetch's request options

@cliffordfajardo
Copy link
Contributor Author

cliffordfajardo commented Oct 2, 2023

Tried using import { fetch } from "@remix-run/web-fetch"; but when I run npm run build in my v2 project, now getting lots of errors:

❌ [ERROR] No matching export in "node_modules/@remix-run/web-fetch/src/lib.js" for import "fetch"

    app/apps/@dwdm-ui/services/server/getAllDCMetroDevices/getAllDCMetroDevices.ts:3:9:
      3 │ import { fetch } from "@remix-run/web-fetch";

Based off the error message, it looks like its trying to find fetch from node_modules/@remix-run/web-fetch/src/lib.js
but that file doesnt export fetch.

Browser

  • node_modules/@remix-run/web-fetch/src/lib.js

Node

  • node_modules/@remix-run/web-fetch/src/lib.node.js

When I import fetch it should try and get it from node_modules/@remix-run/web-fetch/src/lib.node.js

  "exports": {
    ".": {
      "types": "./dist/src/lib.node.d.ts",
      "browser": { 
        "require": "./dist/lib.cjs",
        "import": "./src/lib.js" // <------- 🟡 where its trying to grab fetch from
      },
      "require": "./dist/lib.node.cjs", // <------- 🟡 where its should be trrying to get it from
      "import": "./src/lib.node.js"
    },
    "./package.json": "./package.json",
    "./body": {
      "types": "./dist/src/body.d.ts",
      "import": "./src/body.js"
    },
    "./src/request.js": {
      "types": "./dist/src/request.d.ts",
      "import": "./src/request.js"
    },
  },

CleanShot 2023-10-01 at 17 56 13

@cliffordfajardo
Copy link
Contributor Author

cliffordfajardo commented Oct 2, 2023

I think the temp solution is for me to install node-fetch which does allow me to import nodejs version of fetch, Request, Response, etc

import fetch, {Request, Response} from "node-fetch"

ahh extra dependency =/; I want to be using the fetch from remix 💿

Question

As far as I can tell, I think if someone wants proper typing of fetch in remix, they need to import a node versions
otherwise, how will typescript or even my app know that the fetch I want is from nodejs?

References

@brophdawg11
Copy link
Contributor

Importing from the global namespace is by design in v2 as we want to lean more into the platform/built-ins. If fetch were stable in node 18 we would have completely dropped our polyfills. However, since it's still experimental we have kept them but we don't export them so you still use the polyfilled global. The idea being that eventually when you are ready to use the built-in - you just remove installGlobals() and you don't have to go change a ton of imports. This also means that if we find type discrepancies between native node fetch and our package - it's something we need to address to get our polyfill in line with the native behavior/spec.

It looks we need to dig into the typings and see what our options are there for differences between node fetch and the types in lib.dom. Thank you for the reference above on the differences!

@brophdawg11 brophdawg11 added feat:typescript feat:fetch Issues related to @remix-run/web-fetch labels Oct 2, 2023
@cliffordfajardo
Copy link
Contributor Author

It looks we need to dig into the typings and see what our options are there for differences between node fetch and the types in lib.dom.

Maybe in the future, the remix.env.d.ts can expose remix's version of fetch
When a user clicks to see the typings it takes user's to the @remix-run/web-fetch which is isomorphic ✨

CleanShot 2023-10-02 at 09 28 53@2x

@brophdawg11 brophdawg11 self-assigned this Oct 2, 2023
@brophdawg11
Copy link
Contributor

That would be incorrect though if they don't call installGlobals...

@ericallam
Copy link

@brophdawg11 there are also inconsistencies around installGlobals(), specifically when the custom server does not call install globals and remix-serve is used in development (then remix will call installGlobals for you).

@brophdawg11
Copy link
Contributor

I'm going to close this out because we're adopting the native undici fetch. The recommendation now is that if you are on Node 20+, you should just remove installGlobals. If you are on Node 18, you can use installGlobals({ nativeFetch: true }) to opt-into undici instead of the Remix web fetch polyfill.

@brophdawg11 brophdawg11 closed this as not planned Won't fix, can't repro, duplicate, stale Sep 13, 2024
@brophdawg11 brophdawg11 removed their assignment Sep 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug:unverified feat:fetch Issues related to @remix-run/web-fetch feat:typescript
Projects
None yet
Development

No branches or pull requests

3 participants