Creating workers
Every source createWorker accepts, and the setup for Vite, webpack, Parcel and files you serve yourself.
Every source
createWorker, createEasyWebWorker and new EasyWebWorker(...) accept the same sources. Pick the one that
fits how your project builds and serves its workers.
| Source | Best for | Pool with maxWorkers | reboot / force |
|---|---|---|---|
URL or string | Worker files built by your bundler | Yes | Yes |
Existing Worker | Bundlers that detect new Worker(new URL(...)) | One Worker | No |
Existing Worker[] | Bringing your own pool | The array is the pool | No |
| Function | Workers with no file at all | Yes | Yes |
| Function array | Workers composed from reusable pieces | Yes | Yes |
Vite
Import the worker with ?worker&url. Vite builds the file and gives you its URL, in development and in
production.
import { createWorker } from 'easy-web-worker/createWorker';
import workerUrl from '../getting-started/math.worker?worker&url';
import type { MathWorker } from '../getting-started/math.worker';
// `?worker&url` asks Vite to build the worker and hand back its URL
export const math = createWorker<MathWorker>(workerUrl, {
workerOptions: { type: 'module' },
});type: 'module' is required when the worker file uses import or export, which every defineWorker file
does.
A native Worker you create
webpack 5, Parcel and Vite all detect the expression new Worker(new URL(...)) and bundle the file. Create the
Worker that way and hand it over.
import { createWorker } from 'easy-web-worker/createWorker';
import type { MathWorker } from '../getting-started/math.worker';
// webpack 5, Parcel and Vite detect this expression and bundle the file
const nativeWorker = new Worker(new URL('../getting-started/math.worker.ts', import.meta.url), {
type: 'module',
});
export const math = createWorker<MathWorker>(nativeWorker);The library cannot create that Worker again, so reboot and force are not available. Leave keepAlive at its
default, so the Worker is not terminated when idle.
Your own pool
Pass an array of native Workers and the calls are distributed across them.
import { createWorker } from 'easy-web-worker/createWorker';
import type { MathWorker } from '../getting-started/math.worker';
const createMathWorker = () =>
new Worker(new URL('../getting-started/math.worker.ts', import.meta.url), { type: 'module' });
// the array is the pool: calls are distributed across these Workers
export const math = createWorker<MathWorker>([
createMathWorker(),
createMathWorker(),
createMathWorker(),
]);A file you serve yourself
import { createWorker } from 'easy-web-worker/createWorker';
import type { MathWorker } from '../getting-started/math.worker';
// a worker script that is already built and public only needs its path
export const math = createWorker<MathWorker>('/workers/math.worker.js');A function, with no file at all
import { createWorker } from 'easy-web-worker/createWorker';
export const math = createWorker(({ onMessage }) => {
const fibonacci = (n: number): number =>
n <= 1 ? n : fibonacci(n - 1) + fibonacci(n - 2);
return {
fibonacci,
countTo: onMessage(async (limit: number, message) => {
for (let step = 1; step <= limit; step++) {
message.reportProgress((step * 100) / limit);
}
return limit;
}),
};
});
// both sides are in the same file, so there is no type to import
export const result = math.fibonacci(40); // CancelablePromise<number>The function is the worker. Runtime workers covers its rules.
Cleanup
Dispose the worker when the feature that owns it goes away:
await unwrap(math).dispose();dispose cancels the pending calls, revokes the generated worker URL when there is one, and terminates the
Workers.