Convenient Logging in Web Workers
Interestingly the standard console
object doesn’t quite work how you would expect in web workers.
You can do a console.log
, but it will appear in it’s own tab in the console of devtools.
See below workaround by using a MessageChannel
to send messages to the main thread. We start in our worker, by assigning a MessagePort
to which is passed in via an initial message.
// worker.js
/** @type {MessagePort} */
let mport;
self.onmessage = (event) => {
switch (event.data) {
case "console":
mport = event.ports[0];
break;
}
};
const log = (...args) => {
if (mport) {
mport.postMessage(args);
} else {
// the message port is not yet connected
console.log("worker log", args);
}
};
Some plumbing is then required when the worker is first created to connect the message port.
// main.js
const mchan = new MessageChannel();
const worker = new Worker(new URL("./worker.js", import.meta.url));
worker.postMessage("console", [mchan.port2]);
mchan.port1.onmessage = (event) => {
const args = event.data; // Array of args to console.log()
args.unshift("Worker:"); // Add an arg to identify the worker
console.log.apply(console, args);
};
And that’s it, we have logging from our worker hitting the main thread’s console.
References
This (now aged) Git repository from 2011 - WorkerConsole is a great example of how to use the console
object in a web worker.