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

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

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

【问题讨论】:

    标签: javascript c# interop webassembly umd


    【解决方案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.`);
    })();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-26
      • 2011-07-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多