haxe-js-kit icon indicating copy to clipboard operation
haxe-js-kit copied to clipboard

Dependency on `hxnodejs` is causing issues with socket.io in browser

Open back2dos opened this issue 8 years ago • 9 comments

This is a follow up on #141, however the problems we encounter are more far-reaching.

Among other things hxnodejs:

I'm not sure how to deal with this. As far as socket IO is concerned, I wonder though if the nodejs dependency is all that useful. From the looks of it, it really just uses EventEmitter.

Maybe this would work:

package js.npm.socketio;

#if nodejs
typedef EventEmitter<T> = js.node.events.EventEmitter;
#else
extern class EventEmitter<T> {
  // ...
}
#end

I guess down the line the real question is though whether haxe-js-kit is really intended for pure browser development (i.e. not electron or some other environment that has access to the nodejs APIs).

back2dos avatar Feb 20 '17 09:02 back2dos

I'm aware of this issue, and not sure how to deal with it either. The solution on my end is obvious: I should move browser libs to a separate lib that wouldn't depend on hxnodejs.

But ITOH, I have the feeling forcing -D nodejs in hxnodejs is not a good solution either, and I think it should be removed. IMHO, -D nodejs should be up to the user, and for instance using either XMLHttpRequest, require('http') or why not fetch should be feature-detected at runtime. This would allow "true" browser/server/sys cross-platformness (for example, using webdriver, electron, ...), as well as using npm/node/hxnodejs/js-kit for building browser apps, and so on.

I thought I opened an issue about that in hxnodejs but I can't seem to find it anymore. What do you think ?

clemos avatar Feb 20 '17 11:02 clemos

IMHO, -D nodejs should be up to the user, and for instance using either XMLHttpRequest, require('http') or why not fetch should be feature-detected at runtime.

That's not a bad idea, but it has multiple issues:

  1. the build size will increase, because you're shipping the nodejs-based version in the browser
  2. the way @:jsRequire works will have to be changed, because otherwise said build will just fail while initializing classes

The solution on my end is obvious: I should move browser libs to a separate lib that wouldn't depend on hxnodejs.

Sure, that sounds good to me, although I'm always strongly biased in favor of splitting things :D

OTOH I think haxe-js-kit could still just depend on the browser part of the library.

back2dos avatar Feb 20 '17 12:02 back2dos

the build size will increase, because you're shipping the nodejs-based version in the browser

We could have something like that, with minimal overhead for browsers (pseudocode, obviously) :

static var reqImpl = (require && require('haxe-http-impl')) || fetch || XMLHttpRequest;

We could also build this feature-detection mechanism inside a macro with which we could force or remove whatever implementation.

OTOH I think haxe-js-kit could still just depend on the browser part of the library.

That's the problem, really (as far as I remember): If hxnodejs is anywhere in your project haxelib dependencies, the nodejs flag will be set... (If hxsocketio depends on js-kit, and js-kit depends on hxnodejs, then hxsocketio will be forced to -D nodejs...)

clemos avatar Feb 20 '17 13:02 clemos

We could have something like that, with minimal overhead for browsers (pseudocode, obviously) :

static var reqImpl = (require && require('haxe-http-impl')) || fetch || XMLHttpRequest;

It's not as simple as that. For example fetch and XMLHttpRequest have completely different APIs. And relying on the absence of require breaks down when you run on a project using require.js - yes, apparently that's still a thing ...

If hxnodejs is anywhere in your project haxelib dependencies, the nodejs flag will be set... (If hxsocketio depends on js-kit, and js-kit depends on hxnodejs, then hxsocketio will be forced to -D nodejs...)

Sorry, I meant the other way round: js-kit depends on js-kit-browser and hxnodejs. So one can just use js-kit-browser without the rest.

back2dos avatar Feb 20 '17 13:02 back2dos

It's not as simple as that. For example fetch and XMLHttpRequest have completely different APIs. And relying on the absence of require breaks down when you run on a project using require.js - yes, apparently that's still a thing ...

It was pseudocode, really ;) For instance, haxe-http-impl could have all implementations, primarily for node, but also for out of the box require.js compatibility. I just meant we should think of it the other way around: have all implementations by default, use -D or macros to optimize for this or that runtime.

Sorry, I meant the other way round: js-kit depends on js-kit-browser and hxnodejs. So one can just use js-kit-browser without the rest.

Yeah, but the issue is still more or less the same, in the end ;) I mean, ultimately, I should remove the dependency from js-kit to js-kit-browser to avoid -D nodejs propagation, and this forbids me from reusing anything from one project to the other (even an interface :|)

clemos avatar Feb 20 '17 14:02 clemos

Ultimately, I'll end up maintaining hundreds of packages, like you :D

clemos avatar Feb 20 '17 14:02 clemos

I mean, ultimately, I should remove the dependency from js-kit to js-kit-browser to avoid -D nodejs propagation, and this forbids me from reusing anything from one project to the other (even an interface :|)

I'm not sure we're on the same page here.

For now I singled out the browser externs for socket.io to a separate lib and js-kit could depend on it without any problems, or on a library that has everything that is in js.browser (if you're worried about having many packages) that can be used in isolation, without hxnodejs or -D nodejs or any such thing. But js-kit could still depend on said library, so that users still get exactly the same API as before factoring the browser parts out.

Ultimately, I'll end up maintaining hundreds of packages, like you :D

Hehe, yep :D ... although the overhead can be greatly reduced using adequate tooling, such as travix and haxelib-submit ;)

back2dos avatar Feb 20 '17 14:02 back2dos

I'm not sure we're on the same page here.

I guess not :p Say js-kit depends on both js-kit-browser and js-kit-node, and js-kit-node depends on hxnodejs, then depending on js-kit will set the -D nodejs flag, right ?

clemos avatar Feb 20 '17 14:02 clemos

Indeed it will. But why would one ever do that in a front end project to start with? One would just use js-kit-browser, thus the flag is not set and all is well. Currently, there's no way to use js.browser.SocketIo from js-kit in the browser, which completely defeats the extern's purpose. That's the immediate issue I'm looking to solve.

back2dos avatar Feb 20 '17 15:02 back2dos