Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"ESM Integration proposal for Wasm" support #4551

Open
4 tasks done
Tarnadas opened this issue Aug 9, 2021 · 8 comments
Open
4 tasks done

"ESM Integration proposal for Wasm" support #4551

Tarnadas opened this issue Aug 9, 2021 · 8 comments
Labels
enhancement New feature or request feat: wasm p2-edge-case Bug, but has workaround or limited in scope (priority)

Comments

@Tarnadas
Copy link

Tarnadas commented Aug 9, 2021

Clear and concise description of the problem

Hey! This is a feature request to add support for wasm-bindgen, a library to facilitate high-level interactions between Wasm modules and JavaScript for Rust.

wasm-bindgen has several output formats for generating Wasm <-> JS glue code, which most notably are web and bundler. I was hoping that the bundlertarger would be compatible with Vitejs, but unfortunately it's not. The output for the bundler target roughly looks like this:

// app.js
import * as wasm from "./app_bg.wasm";
export * from "./app_bg.js";
// app_bg.js
import * as wasm from './app_bg.wasm';
// ...
export function myWasmFunction() {
    wasm.myWasmFunction();
}

for this code:

async function main() {
  const wasmModule = await import('./app');
  wasmModule.myWasmFunction();

Suggested solution

There should be an alternative way to bundle Wasm files, which also supports dynamic import function. Probably add this as an option to the serve and build command or if possible auto detect.

Alternative

No response

Additional context

No response

Validations

@husayt
Copy link
Contributor

husayt commented Aug 20, 2021

This might be a similar issue to #3847. One thing is clear not all wasm files are importable by vite as described in the docs. I had to struggle a lot before managing to get rust compiled wasm files to work with vite. Will be great to at least produce some guidance on expected wasm format.

@Fanna1119
Copy link

Fanna1119 commented Nov 5, 2021

This might be a similar issue to #3847. One thing is clear not all wasm files are importable by vite as described in the docs. I had to struggle a lot before managing to get rust compiled wasm files to work with vite. Will be great to at least produce some guidance on expected wasm format.

I agree. I tried using a wasm-markdown packages for a while, had headaches for days trying to solve it, but in the end i gave up when I could not get it to work. Some wasm packages work fine, some don't, I didn't know there are different wasm formats.

@arnoson
Copy link

arnoson commented Nov 30, 2021

Just a quick info, if somebody else is looking here for a solution to load wasm modules generated by wasm pack (with target web, not bundler):

This didn't work for me

import init, { myMethod } from 'myWasmPackage'
init().then(() => console.log(myMethod())

But importing the url with vite works:

import init, { myMethod } from 'myWasmPackage'
import wasmUrl from 'myWasmPackage/my_wasm_package_bg.wasm?url'
init(wasmUrl).then(() => console.log(myMethod())

But getting the bundler target to work with vite would be even better :)

@Fanna1119
Copy link

Just a quick info, if somebody else is looking here for a solution to load wasm modules generated by wasm pack (with target web, not bundler):

This didn't work for me

import init, { myMethod } from 'myWasmPackage'
init().then(() => console.log(myMethod ))

But importing the url with vite works:

import init, { myMethod } from 'myWasmPackage'
import wasmUrl from 'myWasmPackage/my_wasm_package_bg.wasm?url'
init(wasmUrl).then(() => console.log(myMethod())

But getting the bundler target to work with vite would be even better :)

what exactly does the init refer to?

@arnoson
Copy link

arnoson commented Dec 1, 2021

The init function is generated by wasm-pack automatically when using the web target (more info). It loads the actual wasm file so you have to call it before you can use your wasm functions.

@Menci
Copy link
Contributor

Menci commented Jan 16, 2022

I changed the wasm plugin to match the behavior of Webpack 5's asyncWebAssembly and WebAssembly's esm-integration proposal.

Only simple default/named imports/exports of functions and memory object are supported at this time (I didn't test one .wasm file with other type of imports/exports but in theory it should work.). I tested my module syntect-js and it's working as expected (just like in Webpack 5).

My patch is here: Menci@1a19965

It generates the following JS code for .wasm?url imports:

import __vite__initWasm from "/__vite-wasm-helper"
import { __wbindgen_throw as __vite__wasmImport_0_0 } from "/node_modules/@syntect/wasm/dist/syntect_bg.js";
const __vite__wasmModule = await __vite__initWasm({ "./syntect_bg.js": { __wbindgen_throw: __vite__wasmImport_0_0 } }, "/node_modules/@syntect/wasm/dist/syntect_bg.wasm");

export const memory = __vite__wasmModule.memory;
export const __wbg_getcssresult_free = __vite__wasmModule.__wbg_getcssresult_free;
export const __wbg_get_getcssresult_css = __vite__wasmModule.__wbg_get_getcssresult_css;
export const __wbg_set_getcssresult_css = __vite__wasmModule.__wbg_set_getcssresult_css;
export const __wbg_get_getcssresult_error = __vite__wasmModule.__wbg_get_getcssresult_error;
export const __wbg_set_getcssresult_error = __vite__wasmModule.__wbg_set_getcssresult_error;
export const getCSS = __vite__wasmModule.getCSS;
export const highlight = __vite__wasmModule.highlight;
export const __wbg_get_highlightresult_html = __vite__wasmModule.__wbg_get_highlightresult_html;
export const __wbg_get_highlightresult_language = __vite__wasmModule.__wbg_get_highlightresult_language;
export const __wbg_set_highlightresult_html = __vite__wasmModule.__wbg_set_highlightresult_html;
export const __wbg_set_highlightresult_language = __vite__wasmModule.__wbg_set_highlightresult_language;
export const __wbg_highlightresult_free = __vite__wasmModule.__wbg_highlightresult_free;
export const __wbindgen_add_to_stack_pointer = __vite__wasmModule.__wbindgen_add_to_stack_pointer;
export const __wbindgen_free = __vite__wasmModule.__wbindgen_free;
export const __wbindgen_malloc = __vite__wasmModule.__wbindgen_malloc;
export const __wbindgen_realloc = __vite__wasmModule.__wbindgen_realloc;

@Menci
Copy link
Contributor

Menci commented Mar 4, 2022

I have published my solution as a plugin: https://github.com/Menci/vite-plugin-wasm. This works for both modern and legacy browsers.

@sapphi-red
Copy link
Member

ESM Integration proposal for Wasm is now stage 3 and the related PR in HTML spec (whatwg/html#10380) has been merged.
I think we can have it builtin.
Although, I guess it will require top-level-await support and might encounter a bug in rollup (rollup/rollup#4708).

@sapphi-red sapphi-red changed the title Make WebAssembly bundling work with wasm-bindgen "ESM Integration proposal for Wasm" support Sep 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request feat: wasm p2-edge-case Bug, but has workaround or limited in scope (priority)
Projects
None yet
Development

No branches or pull requests

7 participants