是否可以将 C# 项目编译为单文件 UMD JavaScript 库?

Posted

技术标签:

【中文标题】是否可以将 C# 项目编译为单文件 UMD JavaScript 库?【英文标题】:Is it possible to compile C# project into single-file UMD JavaScript library? 【发布时间】:2021-12-29 19:47:39 【问题描述】:

虽然 Blazor 提供 C#/JS 互操作,但它仅适用于浏览器并且专为 SPA 设计。微软似乎没有计划增加对其他场景的支持:https://github.com/dotnet/aspnetcore/issues/37910

是否可以在 javascript 中使用 C# 程序和库而不依赖于 DOM 或其他特定于环境的 API?

【问题讨论】:

【参考方案1】:

可以使用 .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 属性。要将 C# 方法公开给 JavaScript,请使用 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.`);
)();

【讨论】:

以上是关于是否可以将 C# 项目编译为单文件 UMD JavaScript 库?的主要内容,如果未能解决你的问题,请参考以下文章

是否有编译为机器代码的 C C++ C# 编译器 [关闭]

将 Zxing 库编译为 .a 文件并包含在项目中

C#如何编译为二进制可执行文件?

将 C# .net 4 代码编译为 .net 3.5?

将单声道编译为静态库

将 protobuf-net RuntimeTypeModel 编译为 C#,而不是 DLL