Search code examples
.netfilesystemsbrowser-wasm

Does the .NET browser-wasm runtime have a virtual file system?


The new (non-Blazor) browser-wasm runtime of .NET 7 allows for .NET projects to be compiled to WebAssembly and run in the browser. There is limited documentation for this, but a lot of the details are still either undocumented or hard to find.

If you were compiling an app to WASM using Emscripten then you would have a virtual file system, to which you could preload files. Does the browser-wasm runtime have something similar, that would allow preloading files for the normal .NET file API (like IO.FileStream) to access?

There may also be a way to embed files into the WASM file. While no doubt useful for some apps, I need a way to dynamically load/read data files that aren't static data.


Solution

  • I haven't been able to find any documentation on this topic. .NET 7 on WebAssembly uses the Emscripten file system (MEMFS). To embed assets into the file system, you can use DotnetHostBuilder.withConfig. You can access the Emscripten Filesystem API after creating the .NET Runtime.

    Here's how you could embed a picture, create a directory, and access file info about the picture from JS:

    import { dotnet } from './dotnet.js'
      
    const runtime = await dotnet
      .withConfig({
          assets: [
            {
                "virtualPath": "logo.png",
                "behavior": "vfs",
                "name": "logo.png"
            },
        ]
      })
      .create();
    
    const fs = runtime.Module.FS;
    
    fs.mkdir('/new_directory');
    
    const logoInfo = fs.analyzePath('/logo.png');
    if (logoInfo.exists) {
      // Logo was loaded into FS.
    }
    
    let exit_code = await runtime.runMainAndExit(runtime.getConfig().mainAssemblyName, []);
    

    Emscripten API Docs: https://emscripten.org/docs/api_reference/Filesystem-API.html

    dotnet.js ts Definition: https://github.com/dotnet/runtime/blob/main/src/mono/wasm/runtime/dotnet.d.ts