Giter VIP home page Giter VIP logo

dotnetjs's Introduction

NuGet npm CodeFactor codecov

This project is dedicated to providing a user-friendly workflow for consuming .NET C# programs and libraries in any JavaScript environments: be it browsers, node.js or custom restricted spaces, like web extensions for VS Code.

Quick Start

In C# project (.csproj) specify Microsoft.NET.Sdk.BlazorWebAssembly SDK and import DotNetJS NuGet package:

<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">

    <PropertyGroup>
        <TargetFramework>net6.0</TargetFramework>
        <LangVersion>10</LangVersion>
    </PropertyGroup>

    <ItemGroup>
        <PackageReference Include="DotNetJS" Version="0.1.0"/>
    </ItemGroup>

</Project>

To invoke a JavaScript function in C# use JS.Invoke(functionName, args) method. To expose a C# method to JavaScript, use [JSInvokable] attribute:

using System;
using DotNetJS;
using Microsoft.JSInterop;

namespace HelloWorld;

public static class Program
{
    public static void Main ()
    {
        var hostName = JS.Invoke<string>("getName");
        Console.WriteLine($"Hello {hostName}, DotNet here!");
    }

    [JSInvokable]
    public static string GetName () => "DotNet";
}

Publish the project with dotnet publish. A single-file UMD library containing the dotnet runtime and project assemblies will be produced in the "bin" directory. Namespace of the program will be used for both the library file name and main export object. Consume the library depending on the environment:

Browser

<script src="HelloWorld.js"></script>

<script>
    
    // This function is invoked by DotNet.
    window.getName = () => "Browser";
    
    window.onload = async function () {
        // Booting the DotNet runtime and invoking entry point.
        await HelloWorld.boot();
        // Invoking 'GetName()' method from DotNet.
        const guestName = HelloWorld.invoke("GetName");
        console.log(`Welcome, ${guestName}! Enjoy your global space.`);
    };
    
</script>

Node.js

const HelloWorld = require("HelloWorld");

// This function is invoked by DotNet.
global.getName = () => "Node.js";

(async function () {
    // Booting the DotNet runtime and invoking entry point.
    await HelloWorld.boot();
    // Invoking 'GetName()' method from DotNet.
    const guestName = HelloWorld.invoke("GetName");
    console.log(`Welcome, ${guestName}! Enjoy your CommonJS module space.`);
})();

Example Projects

You can find the following sample projects in this repository:

  • Hello World — Consume DotNetJS-compiled program as a global import in browser, CommonJS or ECMAScript (ES) module in node.
  • Web Extension — Consume the library in VS Code web extension, which works with both web and standalone versions of the IDE.
  • Runtime Tests — Integration tests featuring various usage scenarios: async invocations, interop with instances, sending raw byte arrays, streaming, etc.

Build Properties

You can specify the following optional properties in .csproj to customize the build:

  • <Clean>false<Clean> Do not clean the build output folders
  • <LibraryName>CustomName</LibraryName> Provide a custom name for the compiled library and export object.

For example, the following configuration will preserve the WebAssembly build artifacts and produce my-dotnet-lib.js library with my-dotnet-lib export object:

<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">

    <PropertyGroup>
        <TargetFramework>net6.0</TargetFramework>
        <LangVersion>10</LangVersion>
        <Clean>false</Clean>
        <LibraryName>my-dotnet-lib</LibraryName>
    </PropertyGroup>

    <ItemGroup>
        <PackageReference Include="DotNetJS" Version="0.1.0"/>
    </ItemGroup>

</Project>

Compiling Runtime

To compile and test the runtime run the following in order (under Runtime folder):

scripts/install-emsdk.sh
scripts/compile-runtime.sh
scripts/compile-test.sh
npm build
npm test

Publishing Runtime

A memo for the publishing process after modifying JS runtime.

  1. Bump NPM version on ./Runtime/package.json and:
  • npm run build
  • scripts/publish-package.sh
  1. Bump NuGet version on ./DotNetJS/DotNetJS.csproj and:
  • dotnet pack -c Release --output bin
  • dotnet nuget push bin/DotNetJS.{VER}.nupkg --api-key {KEY} --source https://api.nuget.org/v3/index.json
  1. Wait for the package indexing, bump NuGet version on ./Runtime/test/Test.csproj and:
  • script/compile-test.sh
  1. Remind myself that this should be automated.

dotnetjs's People

Contributors

elringus avatar

Watchers

James Cloos avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.