Skip to content
This repository has been archived by the owner on Sep 2, 2023. It is now read-only.

Loading binaries in ES Modules #279

Closed
guybedford opened this issue Feb 27, 2019 · 19 comments
Closed

Loading binaries in ES Modules #279

guybedford opened this issue Feb 27, 2019 · 19 comments

Comments

@guybedford
Copy link
Contributor

guybedford commented Feb 27, 2019

Given that we removed support for .node files in ECMAScript modules, the assumption is that we would use process.dlopen to load binaries.

process.dlopen will create a new binary instance each time it is used or throw an error. Will this still be sufficient for binary loading?

@guybedford
Copy link
Contributor Author

//cc @jasnell

@devsnek
Copy link
Member

devsnek commented Feb 27, 2019

we can just pass .node through to the cjs loader. simple change.

@guybedford
Copy link
Contributor Author

@devsnek that means that any module that imports a .node file is now no longer browser-compatibile unless it does so in a conditional with dynamic import.

@devsnek
Copy link
Member

devsnek commented Feb 27, 2019

huh

@ljharb
Copy link
Member

ljharb commented Feb 27, 2019

Any module using process.binding wouldn’t be either, though?

@addaleax
Copy link
Member

I’m confused – is this about process.dlopen() (official API for loading native addons manually) or process.binding() (deprecated, evil access to Node’s internals)?

@addaleax
Copy link
Member

Also note that process.dlopen() doesn’t have nice effects of require() like ensuring that the returned value is a singleton for each file. When calling it twice on an addon, it will either fail or give you a new instance of the module.

@guybedford
Copy link
Contributor Author

Ah, I mixed this up with process.dlopen yes :) Thanks @addaleax for correcting me here.

@addaleax
Copy link
Member

@guybedford I do feel like ESM should have a better way than raw process.dlopen() for loading addons.

@guybedford
Copy link
Contributor Author

Also note that process.dlopen() doesn’t have nice effects of require() like ensuring that the returned value is a singleton for each file. When calling it twice on an addon, it will either fail or give you a new instance of the module.

Interesting - could it be made into a singleton do you think?

@guybedford
Copy link
Contributor Author

@addaleax sure, will reopen for discussion.

@guybedford guybedford reopened this Feb 27, 2019
@devsnek
Copy link
Member

devsnek commented Feb 27, 2019

they should absolutely be a supported thing to import. they have their own file extension that isn't contentious. all we need to do is pass the request to cjs, like with json

@guybedford
Copy link
Contributor Author

@addaleax I'm not sure process.dlopen is so bad, since most projects bundle their binaries and are the only consumers of it.

@addaleax
Copy link
Member

Also note that process.dlopen() doesn’t have nice effects of require() like ensuring that the returned value is a singleton for each file. When calling it twice on an addon, it will either fail or give you a new instance of the module.

Interesting - could it be made into a singleton do you think?

It would be a breaking change, and I think it depends on whether we ever want to allow loading addons from different contexts/realms.

I don’t think process.dlopen() is terrible, but yeah, it’s also not the most convenient thing to use.

@guybedford
Copy link
Contributor Author

guybedford commented Feb 27, 2019

In addition if you look at usage on npm, most libraries don't do require('./x.node') and rather have a custom wrapper using require('bindings')('./x.node') or similar. These wrappers all effectively would want the process.dlopen-style usage.

@MylesBorins
Copy link
Contributor

I think it is worth considering that wasm modules will hopefully replace the 90% case of native modules. AFAIK many packages that expose native modules expose a CJS interface that in turn brings in the native module itself. I'm going to dig into some of the top native modules and see what interface they expose and post findings in here

@weswigham
Copy link
Contributor

I'm less sure about that - a lot of native module exist to provide bindings for a dynamically linked system lib - even if you can take those libs and compile them to wasm, you'd lose the platform behaviors and dynamic linking (if they even still work without binding to platform APIs). Although it's probably preferable for things like decoders and encoders and other things that were just rewritten as a native module for perf. Upsides and downsides, I suppose.

@MylesBorins
Copy link
Contributor

Can this be closed?

@guybedford
Copy link
Contributor Author

guybedford commented Apr 10, 2019 via email

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants