vite-plugin-wasm

repository·main·Indexed 19 days ago

https://github.com/menci/vite-plugin-wasm

A Vite plugin that adds WebAssembly ESM integration, enabling support for wasm-pack generated modules by allowing them to be imported as standard ES modules. It supports Vite versions 2.x through 8.x and provides automatic glue code generation for .wasm imports, including specialized handling for SSR and Vitest environments.

Tokens
1.2K
Snippets
6
Records
8
Agent score
65%

What's inside vite-plugin-wasm

  1. Workaround for TypeScript WASM typing issues

    main

    Directly importing WASM files (e.g., import ... from "./module.wasm") may result in broken TypeScript typing because the plugin cannot declare a module with Record<string, any> as its named export map.

    To resolve this, use an asterisk import combined with a type assertion to the known type of your WASM module:

    import * as wasmModule from "./module.wasm";
    // Use type assertion if necessary
    const wasm = wasmModule as MyWasmModuleType;
  2. Configure vite-plugin-wasm in Vite

    main

    To enable WebAssembly ESM integration and support wasm-pack generated modules, add wasm() to your Vite plugins array.

    Important: Unless you are targeting very modern browsers by setting build.target to esnext, you must also include vite-plugin-top-level-await to handle the asynchronous loading of WASM modules.

    import wasm from "vite-plugin-wasm";
    import topLevelAwait from "vite-plugin-top-level-await";
    
    export default defineConfig({
      plugins: [
        wasm(),
        topLevelAwait()
      ]
    });
  3. Use vite-plugin-wasm in Web Workers

    main

    To use WASM modules within Web Workers, add wasm() (and topLevelAwait() if necessary) to the worker.plugins configuration object.

    Firefox Compatibility Note: To ensure support for Firefox, do not explicitly set worker.format to es. Leave it at the default value and ensure you are using vite-plugin-top-level-await version 1.4.0 or higher.

    export default defineConfig({
      plugins: [
        wasm(),
        topLevelAwait()
      ],
      worker: {
        // Not needed with vite-plugin-top-level-await >= 1.3.0
        // format: "es",
        plugins: [
          wasm(),
          topLevelAwait()
        ]
      }
    });
  4. How vite-plugin-wasm handles .wasm imports

    main

    The plugin intercepts imports ending in .wasm. It performs the following steps:

    1. URL Resolution: It uses Vite's ?url suffix to determine the correct URL for the WASM binary.
    2. Glue Code Generation: It generates asynchronous glue code that imports a helper module (__vite__initWasm) and uses the resolved URL to initialize the WASM module.
    3. Environment Awareness:
      • In standard client-side builds, it uses a standard import for the WASM URL.
      • In SSR (Server-Side Rendering) or Vitest environments, it automatically converts the WASM binary into a Base64 URI to ensure compatibility where file system URLs might not behave as expected.
  5. Install and use vite-plugin-wasm

    main

    To enable WebAssembly support in your Vite project, import and call the wasm() function within your vite.config.ts (or .js) file. The plugin is designed to run with enforce: 'pre', ensuring it handles .wasm files before other plugins.

    When a .wasm file is imported, the plugin automatically generates glue code that allows you to initialize the module. It handles the underlying URL resolution and provides an initialization function.

    import { defineConfig } from 'vite';
    import wasm from 'vite-plugin-wasm';
    
    export default defineConfig({
      plugins: [
        wasm()
      ]
    });
  6. Fix ESBuild WASM loader errors in Vite < 3.0.3

    main

    If you encounter the error No loader is configured for ".wasm" files while using Vite versions older than 3.0.3, you should either:

    1. Upgrade Vite to >= 3.0.3.
    2. Upgrade vite-plugin-wasm to >= 3.1.0.
    3. As a workaround, exclude the problematic module from dependency optimization in your config:
    export default defineConfig({
      optimizeDeps: {
        exclude: [
          "@syntect/wasm"
        ]
      }
    });
  7. Import the vite-plugin-wasm plugin

    main

    To use the plugin in your Vite configuration, import the default export from vite-plugin-wasm. The entrypoint handles compatibility between different module formats to ensure you can import it directly in your vite.config.js or vite.config.ts.

    import wasm from 'vite-plugin-wasm';
    
    export default {
      // vite config
    };