request.js
request.js copied to clipboard
Use an isomorphic fetching library
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.
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.
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).
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
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
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
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.
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
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.