vite-plugin-wasm-module-workers
TypeScript icon, indicating that this package has built-in type declarations

0.0.2 • Public • Published

vite-plugin-wasm-module-workers (VPWMW)

Handle bundling WASM modules like Satori (Yoga and Resvg WASM) files for both Vite and Cloudflare.

Used on code.charliegleason.com (GitHub repo).

Installation

npm i vite-plugin-wasm-module-workers -D

And then in your vite.config.ts:

import wasmModuleWorkers from 'vite-plugin-wasm-module-workers'

export default defineConfig({
  plugins: [
    wasmModuleWorkers(),
    // ... more plugins
  ],
})

You'll also need to make sure you copy the WASM files to where Cloudflare expects them, usually at the end of the build process.

For example, in your package.json:

{
  "scripts": {
    "build": "remix vite:build && cp -f build/client/assets/*.wasm build/server/assets"
  }
}

How does it work?

Let's say we're using Satori to generate an og:image in our Vite Remix app.

It's important to only import .wasm with ?url, which helps ensure Vite doesn't try to do anything fancy with it.

First, we import the dependencies:

import satori, { init as initSatori } from 'satori/wasm'
import { Resvg, initWasm as initResvg } from '@resvg/resvg-wasm'
import initYoga from 'yoga-wasm-web'

import YOGA_WASM from 'yoga-wasm-web/dist/yoga.wasm?url'
import RESVG_WASM from '@resvg/resvg-wasm/index_bg.wasm?url'

Then, in our default function:

export async function createOGImage(title: string, requestUrl: string) {
  const { default: resvgwasm } = await import(
    /* @vite-ignore */ `${RESVG_WASM}?module`
  )
  const { default: yogawasm } = await import(
    /* @vite-ignore */ `${YOGA_WASM}?module`
  )

  try {
    if (!initialised) {
      await initResvg(resvgwasm)
      await initSatori(await initYoga(yogawasm))
      initialised = true
    }
  } catch (e) {
    initialised = true
  }

  // more fancy code

To trigger the plugin on a file, you'll need to have ?module in there. For example:

import RESVG_WASM from '@resvg/resvg-wasm/index_bg.wasm?url'

const { default: resvgwasm } = await import(
  /* @vite-ignore */ `${RESVG_WASM}?module`
)

Once running, the main things the plugin will look out for are:

  • The constant in import RESVG_WASM from 'yoga-wasm-web/dist/yoga.wasm?url'
  • The variable name in const { default: resvgwasm } ...
  • The constant in ${RESVG_WASM}

[!WARNING] My ability to write regualar expresions is not one of my strengths, so if things aren't working I'd recommend trying to match the imports and const { default: whateverWarmModule } = await import... to what it is in the example above. If you have a better handle on regex and are keen to improve it, check out contributing. I'm not confident how nicely this set up will play with different types of WASM imports, so here be dragons.

VPWMW will take this code on build and convert it to something Cloudflare expects:

)
import YOGA_WASM from './assets/yoga-CP4IUfLV.wasm'
import RESVG_WASM from './assets/index_bg-Blvrv-U2.wasm'
let initialised = false

async function createOGImage(title, requestUrl) {
  const resvgwasm = RESVG_WASM
  const yogawasm = YOGA_WASM
  try {
    if (!initialised) {
      await initWasm(resvgwasm)
      await init(await initYoga(yogawasm))
      initialised = true
    }
  } catch (e) {
    initialised = true
  }

  // more fancy build code

Magic. ✨

Contributing

This plugin also contains some pretty rough regular expressions to convert the code, so if you have any better suggestions for how that could work, I encourage you to open an issue or, even better, a PR.

Package Sidebar

Install

npm i vite-plugin-wasm-module-workers

Weekly Downloads

18

Version

0.0.2

License

MIT

Unpacked Size

15.8 kB

Total Files

8

Last publish

Collaborators

  • superhighfives