是否可以将 C# 项目编译为单文件 UMD JavaScript 库?
Is it possible to compile C# project into single-file UMD JavaScript library?
虽然 Blazor 提供 C#/JS 互操作,但它仅适用于浏览器并且专为 SPA 而设计。微软似乎不打算增加对其他场景的支持:https://github.com/dotnet/aspnetcore/issues/37910
是否可以在 JavaScript 中使用 C# 程序和库而不依赖于 DOM 或其他环境特定的 API?
可以使用 .NET WebAssembly runtime 的自定义构建和与环境无关的 JavaScript 包装器。
这是一个使用这种自定义构建的解决方案,允许将 C# 项目编译成 UMD 库,可以在浏览器、node.js 和自定义受限环境中使用,例如 VS Code 的 Web 扩展:https://github.com/Elringus/DotNetJS
要使用它,请指定 Microsoft.NET.Sdk.BlazorWebAssembly
SDK 并导入 DotNetJS
NuGet 包:
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="DotNetJS" Version="*"/>
</ItemGroup>
</Project>
要将 JavaScript 函数与 C# 方法关联,请使用 JSFunction
属性。要向 JavaScript 公开 C# 方法,请使用 JSInvokable
属性:
using System;
using DotNetJS;
using Microsoft.JSInterop;
namespace HelloWorld;
partial class Program
{
// Entry point is invoked by the JavaScript runtime on boot.
public static void Main ()
{
// Invoking 'dotnet.HelloWorld.GetHostName()' JavaScript function.
var hostName = GetHostName();
// Writing to JavaScript host console.
Console.WriteLine($"Hello {hostName}, DotNet here!");
}
[JSFunction] // The interoperability code is auto-generated.
public static partial string GetHostName ();
[JSInvokable] // The method is invoked from JavaScript.
public static string GetName () => "DotNet";
}
使用 dotnet publish
发布项目。将在“bin”目录下生成一个单文件 dotnet.js
库。根据环境消耗库:
浏览器
<!-- Import as a global 'dotnet' object via script tag. -->
<script src="dotnet.js"></script>
<script>
// Providing implementation for 'GetHostName' function declared in 'HelloWorld' C# assembly.
dotnet.HelloWorld.GetHostName = () => "Browser";
window.onload = async function () {
// Booting the DotNet runtime and invoking entry point.
await dotnet.boot();
// Invoking 'GetName()' C# method defined in 'HelloWorld' assembly.
const guestName = dotnet.HelloWorld.GetName();
console.log(`Welcome, ${guestName}! Enjoy your global space.`);
};
</script>
Node.js
// Import as CommonJS module.
const dotnet = require("dotnet");
// ... or as ECMAScript module in node v17 or later.
import dotnet from "dotnet.js";
// Providing implementation for 'GetHostName' function declared in 'HelloWorld' C# assembly.
dotnet.HelloWorld.GetHostName = () => "Node.js";
(async function () {
// Booting the DotNet runtime and invoking entry point.
await dotnet.boot();
// Invoking 'GetName()' C# method defined in 'HelloWorld' assembly.
const guestName = dotnet.HelloWorld.GetName();
console.log(`Welcome, ${guestName}! Enjoy your module space.`);
})();
虽然 Blazor 提供 C#/JS 互操作,但它仅适用于浏览器并且专为 SPA 而设计。微软似乎不打算增加对其他场景的支持:https://github.com/dotnet/aspnetcore/issues/37910
是否可以在 JavaScript 中使用 C# 程序和库而不依赖于 DOM 或其他环境特定的 API?
可以使用 .NET WebAssembly runtime 的自定义构建和与环境无关的 JavaScript 包装器。
这是一个使用这种自定义构建的解决方案,允许将 C# 项目编译成 UMD 库,可以在浏览器、node.js 和自定义受限环境中使用,例如 VS Code 的 Web 扩展:https://github.com/Elringus/DotNetJS
要使用它,请指定 Microsoft.NET.Sdk.BlazorWebAssembly
SDK 并导入 DotNetJS
NuGet 包:
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="DotNetJS" Version="*"/>
</ItemGroup>
</Project>
要将 JavaScript 函数与 C# 方法关联,请使用 JSFunction
属性。要向 JavaScript 公开 C# 方法,请使用 JSInvokable
属性:
using System;
using DotNetJS;
using Microsoft.JSInterop;
namespace HelloWorld;
partial class Program
{
// Entry point is invoked by the JavaScript runtime on boot.
public static void Main ()
{
// Invoking 'dotnet.HelloWorld.GetHostName()' JavaScript function.
var hostName = GetHostName();
// Writing to JavaScript host console.
Console.WriteLine($"Hello {hostName}, DotNet here!");
}
[JSFunction] // The interoperability code is auto-generated.
public static partial string GetHostName ();
[JSInvokable] // The method is invoked from JavaScript.
public static string GetName () => "DotNet";
}
使用 dotnet publish
发布项目。将在“bin”目录下生成一个单文件 dotnet.js
库。根据环境消耗库:
浏览器
<!-- Import as a global 'dotnet' object via script tag. -->
<script src="dotnet.js"></script>
<script>
// Providing implementation for 'GetHostName' function declared in 'HelloWorld' C# assembly.
dotnet.HelloWorld.GetHostName = () => "Browser";
window.onload = async function () {
// Booting the DotNet runtime and invoking entry point.
await dotnet.boot();
// Invoking 'GetName()' C# method defined in 'HelloWorld' assembly.
const guestName = dotnet.HelloWorld.GetName();
console.log(`Welcome, ${guestName}! Enjoy your global space.`);
};
</script>
Node.js
// Import as CommonJS module.
const dotnet = require("dotnet");
// ... or as ECMAScript module in node v17 or later.
import dotnet from "dotnet.js";
// Providing implementation for 'GetHostName' function declared in 'HelloWorld' C# assembly.
dotnet.HelloWorld.GetHostName = () => "Node.js";
(async function () {
// Booting the DotNet runtime and invoking entry point.
await dotnet.boot();
// Invoking 'GetName()' C# method defined in 'HelloWorld' assembly.
const guestName = dotnet.HelloWorld.GetName();
console.log(`Welcome, ${guestName}! Enjoy your module space.`);
})();