request.js icon indicating copy to clipboard operation
request.js copied to clipboard

Use an isomorphic fetching library

Open ztcollazo opened this issue 2 years ago • 8 comments

I've recently been trying to use an edge environment to deploy a project of mine, and the main error that I get is: Cannot bundle Node.js built-in "stream" imported from "node_modules/@octokit/request/node_modules/node-fetch/lib/index.mjs". However, edge environments do not support Node.js, even though I believed this was an isomorphic library. Apparently, node-fetch is not isomorphic. I don't know how hard this would be or how much time it would take, but I could also open a PR if necessary.

ztcollazo avatar May 14 '22 22:05 ztcollazo

A library like cross-fetch would be suitable for this (I believe that isomorphic-fetch is no longer maintained). One issue I ran into while trying to replace the library 1-for-1 is that cross-fetch does not have the HeadersInit type exported. This could be fixed by simply including a definition for it within this library. Let me know if I should make a PR for this.

safinsingh avatar May 16 '22 15:05 safinsingh

It looks to me like cross-fetch uses node-fetch in the background for Node.js. I'm not sure if tree-shaking will filter this out or not, because this repo is supposed to be isomorphic also. However, it may be better because it's exporting different values based on the environment, whereas request.js is always using node-fetch unless a different fetch is passed (or so it looks to me).

ztcollazo avatar May 16 '22 16:05 ztcollazo

You can specify your own fetch method by setting the options.request.fetch to the fetch function you want to use.

That can alleviate some of your concerns and allow you to use the proper fetch

wolfy1339 avatar Jul 10 '22 15:07 wolfy1339

From the error message, it seems the bundler is complaining about importing node-fetch.

I guess you’re using Netlify edge functions, which support importing absolute path. esm.sh replaces node-fetch with node-fetch-native, you can verify it here: https://esm.sh/v86/@octokit/[email protected]/es2021/request.js

baoshan avatar Jul 10 '22 15:07 baoshan

we don't want to add an isomorphic fetching library as dependency because it would massively increase the bundle size. We want to stay close the web platform, as that's where all the JS runtime environments gravitate towards. fetch is available in most environments, including the Node 18+. We might move away from even including node-fetch in the future and suggesting to use whatever polyfil works for your environment, or ask you to pass your own fetch polyfill as request.fetch option as suggested by @wolfy1339 above

gr2m avatar Jul 12 '22 20:07 gr2m

That probably is the best way to go. The only reason that I mention this issue is that I was having trouble with node-fetch in an edge environment, so until that is somehow changed, I will have to use a Node environment. I did check out node-fetch-native that @baoshan mentioned, and it seemed pretty nice. I may be able to try using NPM overrides to force this project to use it until it no longer includes node-fetch. From my understanding, it has the same API, so it shouldn't break anything.

ztcollazo avatar Jul 12 '22 21:07 ztcollazo

an alternative, if you only use @octokit/request, would be to use @octokit/endpoint instead. It's entirely unopinionated on how you send the request, the endpoint function just gives you generic request options that you can pass to your request method of choice. There is no node-fetch in the dependency tree for @octokit/endpoint

gr2m avatar Jul 13 '22 07:07 gr2m

I'm using @octokit/graphql, but the stack trace showed me that it was @octokit/request erroring. I may be able to completely rewrite the graphql query interface, but it would seem that @octokit/endpoint wouldn't be helpful in that regard, as it is only for generating the request options for the REST endpoints. I'll keep that in mind, though.

ztcollazo avatar Jul 13 '22 14:07 ztcollazo