GoogleChromeLabs / wasm-feature-detect

A small library to detect which features of WebAssembly are supported.

Home Page:https://webassembly.org/roadmap

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

threads test does not run correctly in node

ngzhian opened this issue · comments

$ node --version
v14.8.0
$ cat test-threads.js
var fd = require('./dist/cjs/index.js');

fd.threads().then(supported => {
  if (supported) {
    console.log("threads yes");
  } else {
    console.log("threads no");
  }
});
$ node --experimental-wasm-threads test-threads.js
threads no

I think https://github.com/GoogleChromeLabs/wasm-feature-detect/blob/master/src/detectors/threads/index.js is missing and import of https://nodejs.org/api/worker_threads.html#worker_threads_class_messagechannel when running on node.

Yeah that's reasonable. Do you want to make a PR?

Sure, how should I write the import such that it only runs in node?

The simplest is probably if (typeof require === 'function') + require for the actual import.

commented

Hm, I am not a fan of detecting node via require. I suspect that could end up with broken code when used with bundlers that shim require.

My first thought was to either make a separate node version or the threads() function could take the MessageChannel constructor as an optional parameter. Not sure if that’s a great solution, but happy to discuss other suggestions.

make a separate node version

If we make a separate node version, how will we decide whether to include the node version or the browser version?

Maybe instead of require we can do something like: https://stackoverflow.com/questions/34550890/how-to-detect-if-script-is-running-in-browser-or-in-node-js/34550964 ? Is that acceptable?

If we make a separate node version, how will we decide whether to include the node version or the browser version?

Usually this is done via "browser" field or similar.

This? https://docs.npmjs.com/files/package.json#browser
Not much documentation on what it does :(
I'll keep digging.

Basically, it provides a point of entry for browsers that is used by bundlers (there are couple of other fields, too).

commented

FWIW I don’t like maintaining separate versions either. So if we can find a different solution that doesn’t involve maintaining and testing two builds of this, I’d be very happy :D

What do you both think about function threads(MessageChannelConstructor = MessageChannel)?

It would be nice if users of this package (on nodejs) can simply upgrade the version and have threads detection be fixed without any code change. With your suggestion, they will have to change their code (quite simple, add an import, and pass MessageChannel).

https://stackoverflow.com/questions/34550890/how-to-detect-if-script-is-running-in-browser-or-in-node-js/34550964 might work? I tried it a bit but I couldn't do an import at non-top-level, so maybe it's not possible?

FWIW I don’t like maintaining separate versions either. So if we can find a different solution that doesn’t involve maintaining and testing two builds of this, I’d be very happy :D

Personally, I'd go with require check then. The only thing bundlers usually do about it, is redirecting to a shim (which should still work fine), or complaining about missing module (which is also fine, and encourages user to set "worker_threads" module to empty in bundler config, which they should probably do anyway).

Between "keep same API", "keep same entry file" and "don't do dynamic checks" you need to pick 2 out of 3 :)

commented

I had an idea. What do you think of #35?

Random thought: as far as I understood from the comment, the transferability of SAB test is required only for browsers (specifically, in Firefox which had half-implemented shared memory support).

This means that in Node.js we can probably assume that, as long as the Wasm test passes at all, the feature is supported. If so, can we just do

if (typeof MessageChannel !== "undefined") {
  new MessageChannel().port1.postMessage(new SharedArrayBuffer(1));
}
return WebAssembly.validate(moduleBytes);

?

commented

Hm... that seems correct. Good thought!

Awesome. That should, in particular, fix the fact that #35 turned out to be a breaking change when wasm-feature-detect is used with a bundler (as bundlers suddenly started to find a worker_thread import, trying to resolve it and failing with an error if it wasn't configured as "ignored" module).

I'll make a PR.