hypercore-protocol / hypercore-next

Hypercore 10 is an append only log with multi-writer primitives built in.
MIT License
150 stars 15 forks source link

Tracking issue for browser compatibility #53

Open kasperisager opened 2 years ago

kasperisager commented 2 years ago

This issue tracks the remaining blockers for bundling and running Hypercore in a browser without shims. In no particular order, originally based on https://github.com/hypercore-protocol/hypercore-next/pull/52#issuecomment-954728654:

kasperisager commented 2 years ago

@mafintosh I'm at a bit of an impasse with regards to EventEmitter. It's simple enough to shim with the http://npmjs.com/events module ~but that module cannot be installed without forcing every other dependency that imports events to use it as well~. This means that the onus will be on consumers to install that module if their bundler doesn't automagically include it. esbuild, for example, will throw an error if the module isn't installed.

One option is to adopt the EventTarget web API which is supported as of Node.js 14. It's quite verbose compared to the EventEmitter API, however. Another option is forking the http://npmjs.com/events module under a name that doesn't clash with the builtin module and maybe even just fall back to the builtin module in Node.js. Thoughts?

mafintosh commented 2 years ago

@kasperisager ya, i say we revisit that one later and for now people need to inject that. in practice i haven't heard any "complaints" about that so we can think it through a bit.

kasperisager commented 2 years ago

I can contribute the first use case: The thing I'm currently working on is a browser first, Node.js second type of thing that uses streamx. Being browser first, adding events as a direct dependency seems fine, ~but of course does incur an unnecessary overhead when running the thing in Node.js~.

mafintosh commented 2 years ago

actually zero overhead right, cause node should just skip it?

mafintosh commented 2 years ago

if you manually npm install events before bundling, does that work atm?

kasperisager commented 2 years ago

actually zero overhead right, cause node should just skip it?

That's absolutely true, I missed that! To actually import the events module in Node.js, and not the builtin module, one has to append a slash to the module name:

const events = require('events/')

if you manually npm install events before bundling, does that work atm?

The following import indeed uses the builtin module in Node.js and the events module in browsers, if installed:

const events = require('events')

No cow on the ice 😉 The only gotcha is of course the DX of the whole thing; modules that use the builtin events module without declaring events as a dependency won't Just Work(tm) when bundled.

mafintosh commented 2 years ago

Ya def, on the latter was more practical for now rather than a solution. I don’t mind potentially just including events everywhere, but we should enumerate how many modules that involves and it could be a hard ask for third party ones - let’s see