Search code examples
reactjstypescriptvitewebassembly

loading wasm with react-ts and vitejs


Trying to leave webpack and create-react-app for vitejs. but are having problem with a wasm file.

import init from "swaplab2/dist/swaplab2.wasm?init";
import { setSwaplab2 } from "swaplab2";

export function TestPage(): React.ReactElement {
    const [swaplab2Loaded, setSwaplab2Loaded] = useState(false);

    useEffect(() => {
        //https://vitejs.dev/guide/features.html#webassembly
        if (!swaplab2Loaded) {
            init({})
                .then((instance) => {
                    setSwaplab2(instance);
                    setSwaplab2Loaded(true);
                })
        }
    });

but get an error like

TypeError: WebAssembly.instantiate(): Import #0 module="env" error: module is not an object or function

If I add something like

          init({ env: import.meta.env })

I instead get

TypeError: WebAssembly.instantiate(): Import #72 module="wasi_snapshot_preview1" error: module is not an object or function

Feels like I am on the wrong path here, and would appreciate a pointer


Solution

  • Swaplab2 is compiled without the standalone switch and uses emscripten ABI and not WASI https://github.com/emscripten-core/emscripten/wiki/WebAssembly-Standalone

    Was easy enough to get around with vitejs

    import swaplab2Url from "swaplab2/dist/swaplab2.wasm?url";
    import { Swaplab2Module, setSwaplab2 } from "swaplab2";
    
    export function TestPage(): React.ReactElement {
        const [swaplab2Loaded, setSwaplab2Loaded] = useState(false);
    
        useEffect(() => {
            //https://vitejs.dev/guide/features.html#webassembly
            if (!swaplab2Loaded) {
                Swaplab2Module({ locateFile: (path) => (path.endsWith(".wasm") ? swaplab2Url : path) }).then((loaded) => {
                    setSwaplab2(loaded);
                    setSwaplab2Loaded(true);
                });
            }
        });