dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
14.56k stars 4.55k forks source link

[browser] Provide "single-file" deployment #86162

Open pavelsavara opened 1 year ago

pavelsavara commented 1 year ago

Similar to WasmSingleFileBundle in wasi. Bundle all the files inside one JS or maybe .wasm as separate, but not 20 files. Enable users to use 3rd party solutions like webpack.

Currently we use ES6 dynamic import in runtime code. In few places we disable webpack on it by /* webpackIgnore: true */, I'm not sure this is a problem.

ghost commented 1 year ago

Tagging subscribers to 'arch-wasm': @lewing See info in area-owners.md if you want to be subscribed.

Issue Details
Bundle all the files inside one JS or maybe .wasm as separate, but not 20 files.
Author: pavelsavara
Assignees: pavelsavara
Labels: `arch-wasm`, `area-System.Runtime.InteropServices.JavaScript`
Milestone: Future
RPGillespie6 commented 1 year ago

It would be nice to have the option of bundling everything into a single distributable JS file, similar to OpenCV where the wasm and any dependencies are base64 encoded into a single file: https://docs.opencv.org/3.4/opencv.js

The primary motivation is portability to non-.NET web applications. For example, I work for a medical software company where most of our on premises solutions are .NET (for example: https://radformation.com/autocontour/autocontour).

We are interested in leveraging WebAssembly in order to bring medical image viewers originally written in C# to the browser. And so far, the results are really promising. It's just a bit of a pain to embed the C# into a page since you need to drop 20+ files into the webserver root and fetch at least 4:

    <script type='module' src="./main.js"></script>
    <script type='module' src="./dotnet.js"></script>
    <link rel="preload" href="./mono-config.json" as="fetch" crossorigin="anonymous">
    <link rel="prefetch" href="./dotnet.wasm" as="fetch" crossorigin="anonymous">

Compared to OpenCV where we can start doing image contouring with a single dependency - opencv.js.

It seems like most of the HTTP requests are coming from dotnet.json reading mono-config.json so seems like it would not be too hard to add a preprocessing step where mono-config.json is read at compile time and base64 encoded into dotnet.js.

Download size is not an issue because for something like this - in most cases it would be downloaded once and then cached for subsequent page refreshes. So for this particular case I'm not really interested in building an "app" so much as I am interested in building a "library" that apps can use.

For example, I would compile my CTImageViewer.cs to ctImageViewer.js which can be dropped into any web app and wired up to an HTML5 canvas, and bam, now that app can display CT images in browser.