Seperate Node codegen target?

There was some discussion in the chat around fetch bindings. There’s some difficulty in writing universal bindings because the web API relies on globals, and node relies on a particular package that implements the API. I would really like to avoid dynamic require at all costs, so that makes me think that we should have a separate codegen target for Node. This target would be identical to JS, except for FFI resolution:

  • First look for a Foo.node.js file
  • Otherwise fallback to a Foo.js file.

I think this is a fairly straightforward way to make universal bindings. What do y’all think?

The approach seems simple enough, but what’s wrong with just providing two bindings - one for Node and one for the DOM? Abstracting over these is as simple as passing a Fetch object around in function arguments. What’s the use case for a universal binding? Do we have any other use cases that would justify compiler changes?

1 Like

The larger fetch API is comprised of a lot of other globals for web (Request, ReadableStream, Headers, and more). It’s not really practical to do a single Fetch object.

So can you not package up all the globals in a single FetchGlobals type and pass that around instead?

Yes, it’s likely always possible to factor things out into an opaque implementation, which also requires any downstream users to deal with this, and structure their program around it. I’m just wondering if we considered node as a separate target, then that would be a burden that users wouldn’t have to deal with. It’s not a question of type-safety at this point, since the implementation object is an opaque foreign entity regardless.

Right, yeah. It would indeed be nice if users didn’t have to deal with this, but if that’s the goal I feel like dynamic require may be the lesser evil? I can imagine this approach being quite awkward, as it will require people to learn how to configure their build setups to pass the correct arguments to purs directly in all the places it’s being invoked (including in their IDE setups), but in the majority of cases there are other tools in between the user and purs. It’s not too hard to imagine situations where, say, you try to build for Node but your editor keeps rebuilding and reverting you back to a normal JS build, for instance, and I think that could be quite confusing / irritating.

1 Like