Skip to content
Advertisement

How to create a module worker in javascript

I am working on a program that relies heavily on web workers. But I am unable to get them to function as required. This is just a minified example but the format is more or less similar.

I have 4 files:

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Hello World!</title>
  </head>
  <body>
      <button id="btn">GO</button>
      <script src="./index.js" type="module"></script>
  </body>
</html>

index.js

const worker = new Worker("./worker.js", {type: "module"})

worker.addEventListener("message", async ({ data }) => {
    console.log(data);
});

worker.onerror = function (event) {
    throw new Error(event.message + " (" + event.filename + ":" + event.lineno + ")");
}

window.sendMessage = function (args) {
    worker.postMessage(args);
};

async function onclick() {
    sendMessage("World")
}

document.getElementById("btn").addEventListener("click", onclick, false);

worker.js

import * as p from "hello.js"

console.log("Worker Started")

onmessage = function (e) {
    p.greet(e.data)
}

hello.js

export function greet(who){
    alert("Hello " + who)
}

The worker should output “Worker Started”.

When the button is clicked, the UI thread will send a message to the worker which will then call the greet function.

However the worker immediately errors and returns a value via worker.onerror

The value it returns in Chromium(and Chromium based) is undefined

Uncaught Error: undefined (undefined:undefined)
    at Worker.worker.onerror (index.js:8:11)

I have tested this across various browsers on 2 computers with 3 different operating systems with no success.

From what I understand. Firefox does not support this the way I am doing it.

Uncaught Error: SyntaxError: import declarations may only appear at top level of a module (http://localhost:8000/worker.js:1)

I have taken a look at this answer here https://stackoverflow.com/a/33432215/19140286 however It does not let me import a file into my worker function.

Running chrome with chromium --allow-file-access-from-files does not solve the issue

examples are run with a local server via

 python -m http.server

Here is a repository with the files https://github.com/KivalM/web-workers

Answer

Such an error on a Worker without a .message, .filename, or .lineno points toward a network error, if it was a script error you’d get these filled.
Maybe your worker URL is also invalid, but at least your module one is.
If you don’t use module maps, you must prepend ./ to relative import URLs.

import * as p from "./hello.js"

Once this is fixed, you’ll face a new error, a script error this time: alert() is only accessible in Window contexts. You can’t call this method from a Worker. You should anyway avoid its use even in Window contexts because its influence on the JS environment is far from being obvious and usually isn’t as useful in debugging as the Console API.

Advertisement