Astro Worker lets you use Web Workers in Astro, with server-side workers polyfilled by web-worker.
npm install @astropub/worker
Usage
Import @astropub/worker in your Astro configuration.
import worker from "@astropub/worker" import { defineConfig } from "astro/config" export default defineConfig({ integrations: [ worker(), ], })
Creating a Worker
Create a worker in any Astro project.
--- /** @file /src/scripts/worker.ts */ addEventListener("message", (event) => { console.log("client said:", event.data) postMessage(event.data) })
Using a Worker
Import the worker into Astro frontmatter.
--- /** @file /src/pages/index.astro */ const worker = new Worker("../scripts/worker.ts", { type: "module" }) worker.addEventListener("message", (event) => { console.log("worker said:", event.data) }) worker.postMessage("Hello") --- <html lang="en"> <head> <meta charset="utf-8" /> <link rel="icon" type="image/svg+xml" href="/favicon.svg" /> <meta name="viewport" content="width=device-width" /> <meta name="generator" content={Astro.generator} /> <title>Example</title> </head> <body> <h1>Example</h1> </body> </html>
Alternatively, import the worker into a client-side script.
--- /** @file /src/pages/index.astro */ --- <html lang="en"> <head> <meta charset="utf-8" /> <link rel="icon" type="image/svg+xml" href="/favicon.svg" /> <meta name="viewport" content="width=device-width" /> <meta name="generator" content={Astro.generator} /> <title>Example</title> </head> <body> <h1>Example</h1> </body> </html> <script> const worker = new Worker("../scripts/worker.ts", { type: "module" }) worker.addEventListener("message", (event) => { console.log("worker said:", event.data) }) worker.postMessage("Hello") </script>
How it works
This integration works by noticing when Worker or SharedWorker are used in
scripts. If they are, this integration corrects any string references to files.
/* before (does not work in Astro) */ const worker = new Worker('../path/to/worker.js') /* after (does work in Astro) */ const worker = new Worker(new URL('../path/to/worker.js', import.meta.url))
If the integration detects a server-side Worker then a polyfill is applied.
--- /* before (does not work in Astro) */ const worker = new Worker('../path/to/worker.js') ---
--- /* after (does work in Astro) */ import "@astropub/worker/polyfill" const worker = new Worker(new URL('../path/to/worker.js', import.meta.url)) ---
Enjoy!
Code original to this project is licensed under the MIT No Attribution License.
Code from web-worker is licensed under the Apache License (Apache-2.0), copyright Jason Miller.