A MSDN article (following up on this blog post) talk about how you can now call .NET assemblies from JavaScript. But the instructions don’t work for me.
I started with dotnet new wasmbrowser
to make a project, producing a very simple csproj:
<Project Sdk="Microsoft.NET.Sdk.WebAssembly">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
</Project>
The project itself can be run and works. But I need to use it from an existing TypeScript app built on create-react-app, and that doesn’t work.
Problem 1: the instructions mention an AppBundle folder that doesn’t exist.
The dotnet.js file is used to create and start the .NET WebAssembly runtime. dotnet.js is generated as part of the build output of the app and found in the AppBundle folder:
bin/{BUILD CONFIGURATION}/{TARGET FRAMEWORK}/browser-wasm/AppBundle
…
Important
To integrate with an existing app, copy the contents of the AppBundle folder so that it can be served along with the rest of the app. For production deployments, publish the app with the
dotnet publish -c Release
command in a command shell and deploy theAppBundle
folder with the app.
Alas, even dotnet publish
doesn’t create an AppBundle folder. However the binDebugnet8.0wwwroot_framework
folder appears to contain the kinds of files I would expect to deploy, such as dotnet.js, mscorlib.wasm, Microsoft.CSharp.wasm and NameOfMyProject.wasm. So I copy this folder into a src/dotnet folder in my create-react-app app, and I write a dotnet.js file that tries to use it:
import { dotnet } from 'dotnet/_framework/dotnet.js';
dotnet
.withDiagnosticTracing(false)
.withApplicationArgumentsFromQuery()
.create().then(async ({ setModuleImports, getAssemblyExports, getConfig }) => {
console.log(`NOTE: Execution doesn't get this far`);
setModuleImports('main.js', {
window: {
location: {
href: () => globalThis.window.location.href
}
}
});
const config = getConfig();
const exports = await getAssemblyExports(config.mainAssemblyName);
const text = exports.MyClass.Greeting();
console.log(text);
});
Problem 2: import { dotnet }
causes the following errors to appear in the console (running react-scripts start
):
ERROR in ./src/dotnet/_framework/dotnet.js 1056:28-44
Module not found: Error: Can't resolve 'module' in 'C:...UIsrcdotnet_framework'
ERROR in ./src/dotnet/_framework/dotnet.js 1527:24-41
Module not found: Error: Can't resolve 'process' in 'C:...UIsrcdotnet_framework'
In addition, the call to create()
causes several runtime errors in the browser console, all of which mention “blazor.boot.json”. Here are the first three:
Security Error: Content at http://localhost:3000/ may not load or link to file:///C:/Dev/.../UI/src/dotnet/_framework/blazor.boot.json.
MONO_WASM: Failed to load config file ./blazor.boot.json TypeError: NetworkError when attempting to fetch resource. A@http://localhost:3000/static/js/src_AuthenticatedApp_tsx.chunk.js:43311:30
s@http://localhost:3000/static/js/src_AuthenticatedApp_tsx.chunk.js:44179:23
./src/dotnet/_framework/dotnet.js/Pe/<@http://localhost:3000/static/js/src_AuthenticatedApp_tsx.chunk.js:44165:127
...
Uncaught (in promise) Error: Failed to load config file ./blazor.boot.json TypeError: NetworkError when attempting to fetch resource. A@http://localhost:3000/static/js/src_AuthenticatedApp_tsx.chunk.js:43311:30
s@http://localhost:3000/static/js/src_AuthenticatedApp_tsx.chunk.js:44179:23
./src/dotnet/_framework/dotnet.js/Pe/<@http://localhost:3000/static/js/src_AuthenticatedApp_tsx.chunk.js:44165:127
...
Any ideas?