Skip to content

Web Worker support #112

@donmccurdy

Description

@donmccurdy

With #108 we'll support using Web Workers to offload local calculation for tilesets and rasters from the main thread. Unfortunately, using Web Workers packaged in libraries — as opposed to final applications — has been a minefield in the JavaScript ecosystem for years. If there is a "right" way to package Web Workers so that they'll work in all combinations of ...

  • environment: Browser, Node.js
  • format: ESM, CJS
  • bundler: Vite, Webpack 5+, Parcel 2+, ...

... I have never found it. When a particular solution fails, it doesn't necessarily throw a runtime error we can catch and respond to. In some cases the build step (notably Parcel and Vite) may simply fail if a Web Worker cannot be resolved, which gives us no way to 'fall back' to a main-thread implementation.

I'm opening this thread to document the current state of support in @carto/api-client.

Environments

  • ✅ Browser
  • ❌ Node.js

Consider npm:web-worker if Node.js workers are needed.

Formats

  • ✅ ESM
  • ❌ CJS

There are a few ways to potentially add support for workers in CJS builds, but I'm not sure what environments/bundlers/users we'd be targeting, and trying to guess at the requirements here could add a lot of complexity. Consider dropping CJS support entirely after Node.js v18 EOL, the last version that cannot use require(...) to load ESM modules. Users bundling for CommonJS may be able to configure their bundlers compile ESM to CJS if needed, or to use require(esm) support in Node.js v20+.

Bundlers

  • ✅ Vite
  • ✅ Webpack 5
  • ❌ Parcel 2

Currently Vite and Parcel appear to be mutually exclusive, each supporting only one of the statements below:

// ❌ vite, ✅ parcel
const worker = new Worker(new URL('./worker.js', import.meta.url), {type: 'module'});

// ✅ vite, ❌ parcel
const worker = new Worker(new URL('@carto/api-client/worker', import.meta.url), {type: 'module'});

User could configure Vite to handle './worker.js' by setting optimizeDeps.exclude = ['@carto/api-client'] in their vite.config.js file, but because Vite is used far more often, I think we have to use the Vite-compatible choice for now. I'm tracking these issues, which if resolved would allow us to support both Vite and Parcel:

We could also report the issue to Parcel — they support Web Workers but I haven't found an existing issue about the errors. With the current approach in @carto/api-client Parcel users will see this error on build:

@parcel/core: Failed to resolve '@carto/api-client/worker' from './node_modules/@carto/api-client/build/api-client.js'

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions