web-worker

repository·main·Indexed 22 days ago

https://github.com/developit/web-worker

A cross-platform implementation of the Web Worker API that provides a unified, web-compatible Worker interface for both Node.js and the browser. In Node.js, it implements the API on top of worker_threads, while in the browser, it acts as an alias for the native Worker API. It supports DOM-style events, WorkerGlobalScope emulation, Module Workers via { type: 'module' }, and instantiation using relative URLs or Data URLs.

Tokens
2.2K
Snippets
10
Records
10
Agent score
76%

What's inside web-worker

  1. Use web-worker for cross-platform Worker support

    main

    The web-worker package provides a unified, web-compatible Worker implementation that works identically in both the browser and Node.js.

    • In Node.js: It implements the Web Worker API on top of Node's worker_threads.
    • In the browser: It acts as an alias for the native Worker API.

    This allows you to write worker code once and publish it as an npm module that runs in any environment. It emulates browser-style WorkerGlobalScope within the worker and supports DOM-style events (Event.data, Event.type, etc.) and event handler properties (worker.onmessage = ...).

    import Worker from 'web-worker';
    
    const worker = new Worker('data:,postMessage("hello")');
    worker.onmessage = e => console.log(e.data);  // "hello"
  2. Load workers using relative URLs

    main

    To load a worker file relative to the current module (especially important in Node.js to avoid issues with process.cwd()), use new URL('./path/to/worker.js', import.meta.url). This ensures the worker path is resolved correctly regardless of the application's base directory.

    import Worker from 'web-worker';
    
    const url = new URL('./worker.js', import.meta.url);
    const worker = new Worker(url);
    
    worker.addEventListener('message', e => {
      console.log(e.data);
    });
    
    worker.postMessage('hello');
    
    // Inside worker.js:
    // addEventListener('message', e => {
    //   if (e.data === 'hello') {
    //     postMessage('hiya!');
    //   }
    // });
  3. Implement logic inside a Worker (WorkerGlobalScope)

    main

    When code runs inside a worker thread created by this library, it operates within a mocked WorkerGlobalScope. This environment emulates the Web Worker API to allow the same code to run in both browsers and Node.js.

    Available Globals and Methods:

    • self: The global scope object.
    • postMessage(data, transferList): Sends data back to the main thread.
    • close(): Terminates the worker thread.
    • importScripts(...urls): Synchronously imports scripts from the provided URLs. Supports data: URLs.
    • addEventListener(type, handler) / removeEventListener(type, handler): Standard DOM event listener methods.
    • self.name: The name assigned to the worker during construction.
    // Inside the worker script
    self.addEventListener('message', (event) => {
      console.log('Message from main thread:', event.data);
      self.postMessage('Response from worker');
    });
    
    // Using importScripts (classic workers)
    importScripts('https://example.com/library.js');
    
    // Terminating the worker
    if (event.data.command === 'stop') {
      self.close();
    }
  4. Create Module Workers

    main

    To use ES Modules within a worker, set the type option to 'module' during construction. This allows the worker to use import statements.

    Note: If using data: URLs as the worker source with type: 'module', Node.js 12.10+ is required. If not supported, the library will attempt to fall back to a 'classic' worker using evaluateDataUrl.

    const worker = new Worker('data:text/javascript,import { func } from "./mod.js"; func();', {
      type: 'module'
    });
  5. Instantiate Workers using Data URLs

    main

    You can create a worker directly from a string using a Data URL. This works for both classic and module workers.

    import Worker from 'web-worker';
    
    const worker = new Worker(`data:application/javascript,postMessage(42)`);
    worker.addEventListener('message', e => {
      console.log(e.data);  // 42
    });
  6. Use Module Workers with `{ type: 'module' }`

    main

    You can instantiate Module Workers by passing { type: 'module' } in the options object.

    • Node.js: Supported in Node 12.8+ using the web-worker plugin, leveraging native ES Modules.
    • Browser: Supported natively in Chrome 80+. For other browsers, use worker-plugin or rollup-plugin-off-main-thread.

    Usage is identical across environments.

    import Worker from 'web-worker';
    
    const worker = new Worker(
      new URL('./worker.mjs', import.meta.url),
      { type: 'module' }
    );
    
    worker.addEventListener('message', e => {
      console.log(e.data);
    });
    
    worker.postMessage('https://httpstat.us/200');
    
    // Inside worker.mjs:
    // import fetch from 'isomorphic-fetch';
    // addEventListener('message', async e => {
    //   const url = e.data;
    //   const res = await fetch(url);
    //   const text = await res.text();
    //   postMessage(text);
    // });
  7. Access the Worker API in the browser

    main

    This module provides a safe way to access the native Worker API in browser environments. It exports the global Worker constructor if it is defined in the current environment; otherwise, it returns undefined. This allows for feature detection and prevents runtime errors in environments where Web Workers are not supported.

    import Worker from 'web-worker/browser';
    
    if (Worker) {
      const myWorker = new Worker('worker.js');
    } else {
      console.log('Web Workers are not supported in this environment.');
    }
  8. Import the default Worker constructor

    main

    The web-worker package provides a default export that acts as a constructor for a Worker instance. This allows you to instantiate workers using the standard new Worker(...) pattern, typically used for offloading heavy computations or background tasks in a web environment.

    import Worker from 'web-worker';
    
    const myWorker = new Worker('worker-script.js');
  9. Use the Worker class in Node.js

    main

    The web-worker package provides a web-compatible Worker implementation for Node.js environments. It uses Node's worker_threads under the hood but exposes a DOM-style API.

    To use it, import the default export. The module automatically detects if it is running in the main thread or a worker thread and provides the appropriate interface.

    Key Features:

    • Uses DOM-style events (message, error, close).
    • Supports event handler properties like worker.onmessage.
    • Accepts a module URL or a data: URL.
    • Supports the { type: 'module' } option for Module Workers.
    import Worker from 'web-worker';
    
    const worker = new Worker('./worker-script.js', { 
      name: 'my-worker', 
      type: 'module' 
    });
    
    worker.onmessage = (event) => {
      console.log('Received:', event.data);
    };
    
    worker.postMessage({ hello: 'world' });
    
    worker.terminate();
  10. Configure Worker construction options

    main

    When instantiating a new Worker, you can pass an optional options object to configure its behavior.

    OptionTypeDefaultDescription
    namestringundefinedThe name of the worker, available as self.name within the worker scope.
    typestring'classic'Set to 'module' to create a Module Worker.
    const worker = new Worker(url, {
      name: 'my-worker-name',
      type: 'module'
    });