javascriptweb-workeres6-modulesbrowser-feature-detection

Javascript feature detect module support for Web Workers


As of Chrome 80, you can create module type workers with new Worker("worker.js", { type: "module" }), and then use module features like import in the worker script. However other browsers are still working on support for this, so using it needs feature detection and a fallback.

Is there a convenient and simple way to feature detect module support for workers?

Note on some platforms (e.g. Cordova) creating workers is actually non-trivial and involves a bunch of workarounds, so something that works in pure JS would be ideal.


Solution

  • As every initOptions features, you can use what I call a "dictionary trap".

    It is an Object on which you'd set a property getter (the one you want to test), and let this getter switch a boolean when it's been gotten by the constructor you are testing. This works with a lot of such features, and Worker's type is no exception here.

    The only things you'll want to be careful with a Worker is to avoid to actually start one (starting even an empty Worker means a new Event loop has to run, a new JS context and these are not small operations) and avoid it to make an useless network request (even a 404 eats resources).

    So here is such a tester, using the string "blob://" has a way to avoid both these situations.

    function supportsWorkerType() {
      let supports = false;
      const tester = {
        get type() { supports = true; } // it's been called, it's supported
      };
      try {
        // We use "blob://" as url to avoid an useless network request.
        // This will either throw in Chrome
        // either fire an error event in Firefox
        // which is perfect since
        // we don't need the worker to actually start,
        // checking for the type of the script is done before trying to load it.
        const worker = new Worker('blob://', tester);
      } finally {
        return supports;
      }
    }
    
    console.log( supportsWorkerType() );