Astro Worker lets you use Web Workers in Astro, with server-side workers polyfilled by web-worker.
npm install @astropub/worker
Import @astropub/worker in your Astro configuration.
import worker from "@astropub/worker"
import { defineConfig } from "astro/config"
export default defineConfig({
integrations: [
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)
})
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>
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.