--experimental-web-worker CLI flag.A mostly browser-compatible implementation of Web Workers of the HTML Standard,
implemented on top of node:worker_threads. Threads created with it
are given the DedicatedWorkerGlobalScope API (self,
name, location, navigator, postMessage(), close(), and
importScripts()), in addition to the usual Node.js globals, such as process.
// worker.js addEventListener('message', (event) => { postMessage(`${event.data} from ${name}!`); });
// main.js const worker = new Worker('./worker.js', { name: 'greeter' }); worker.addEventListener('message', (event) => { console.log(event.data); // Prints: Hello from greeter! worker.terminate(); }); worker.postMessage('Hello');
Because their lifetime and sharing model depend on origins and
browsing contexts, Node.js does not currently implement SharedWorker.
Worker scripts are read synchronously from the local file system or from memory rather than fetched over the network, which changes which URLs are accepted and how failures are reported:
new Worker()andimportScripts()accept onlyfile:,data:, andblob:URLs. Any other scheme makesnew Worker()throw aNotSupportedErrorandimportScripts()throw aNetworkError.- A script that cannot be read makes
importScripts()throw aNetworkError; fornew Worker()it fires anerrorevent at theWorkerobject. - Redirects, the
nosniffcheck, and HTTP MIME type validation do not apply. MIME types are validated only fordata:andblob:URLs. Thecredentialsoption is validated for API compatibility but has no effect, since no network request is made. - On the main thread, relative script URLs are resolved against the current working directory, because there is no document base URL. Within a worker they are resolved against the worker's own URL (as is done in the spec).
- For
blob:URLs, the script must be held in memory, so blobs backed by a file, such as those returned byfs.openAsBlob(), cannot be used.
Besides script loading, mentioned above:
- Node.js has no origin model, so same-origin and cross-origin distinctions do
not exist and
location.originis'null'for every supported scheme. close()terminates the worker immediately instead of following the specification's "closing flag" algorithm, so code remaining in the current task afterclose()is not executed.- The worker global is the normal Node.js global object with
DedicatedWorkerGlobalScopeinserted into its prototype chain, rather than a fresh global created from the interface. Node.js globals such asprocess,Buffer, andrequire()remain available to worker scripts. ErrorEvents dispatched atWorkerinstances includemessageanderror, butfilename,lineno, andcolnoare always'',0, and0. An uncaught exception terminates the worker thread, and an unhandlederrorevent is not propagated further: it neither reaches the parent's global scope nor affects the exit code of the process.- The following
WorkerGlobalScopeevents are never dispatched, although their handler properties exist:languagechange,online, andoffline, since these concepts do not exist in Node.js;rejectionhandledandunhandledrejection, since Node.js exposes the equivalent does not implement thePromiseRejectionEventinterface or the per-rejectionpreventDefault()behavior required by the HTML Standard.
Every Web Worker is backed by a node:worker_threads Worker, so the
two APIs share their threading, structured clone, and transfer semantics.
Inside a worker, [worker_threads.parentPort][] is the port behind
self.postMessage() and the worker's message events, isMainThread is
false, and workerData is undefined.
Web Workers, like node:worker_threads workers, keep the event loop alive by
default. In Node.js, Web Workers implement the Refable protocol, and can be
ref'd and unref'd using process.ref(worker) and process.unref(worker).
As a rule of thumb, use node:worker_threads directly when a program
needs workerData, a custom env or execArgv, resource limits, stdio
redirection, the 'online' and 'exit' events, or worker.threadId;
Worker accepts only the name, type, and credentials options and,
per the specification, its terminate() returns undefined, rather than
a promise. Threads started through node:worker_threads are ordinary
Node.js threads and do not get the worker global scope APIs.