Load wasm in VSCode Web Extension

Viewed 246

I'm trying to load a wasm module with a VSCode web extension.

I started from the "lsp-web-extension-sample". Within the server directory, I created a simple rust lib with wasm-bindgen, it successfully compiles with wasm-pack. When I call the init function from the rust pkg output, it basically does this:

input = new URL("my-ext.wasm", import.meta.url)
fetch(input)

I get the following error: "TypeError: failed to fetch", without more explanations. This error happens when testing with @vscode/test-web as well as when testing with the vsce package version.

Any idea what to do? Is there any example out there of a wasm web extension for vscode?

2 Answers

I was able to get the work done by loading wasm inline.

webpack.config.js

  module: {
    rules: [
      // ...,
      {
        test: /\.wasm$/,
        type: "asset/inline",
      },
    ],
  },

Accepted solution didn't work for me (WASM generated by wasm-pack), but this did:

https://github.com/SonOfLilit/vscode-web-wasm-rust

It involved writing a webpack WASM Loader plugin (and patching webpack to make that possible, PR submitted) to use this loader:

/******/    /* webpack/runtime/wasm loading */
/******/    (() => {
/******/        __webpack_require__.v = (exports, wasmModuleId, wasmModuleHash, importsObj) => {
/******/            var vscode = require('vscode');
/******/            var wasmPath = __webpack_require__.p + wasmModuleHash + '.module.wasm';
/******/            var req = vscode.workspace.fs.readFile(vscode.Uri.file(wasmPath));;
/******/            return req
/******/                .then((bytes) => (WebAssembly.instantiate(bytes, importsObj)))
/******/                .then((res) => (Object.assign(exports, res.instance.exports)));
/******/        };
/******/    })();

as well as setting __webpack_public_path__ in activate before trying to import the WASM:

export function activate(context: vscode.ExtensionContext) {
  __webpack_public_path__ =
    context.extensionUri.toString().replace("file:///", "") + "/dist/web/";

  let disposable = vscode.commands.registerCommand(
    "vscode-rust-web.helloWorld",
    () => {
      require("rust-wasm").then((rust: any) => {
        vscode.window.showInformationMessage(rust.greet());
      });
    }
  );

  context.subscriptions.push(disposable);
}
Related