JavaScript [JSImport]/[JSExport] interop với dự án WebAssembly Browser App

Nguồn: [JavaScript [JSImport]/[JSExport] interop with a WebAssembly Browser App project](https://learn.microsoft.com/en-us/aspnet/core/client-side/dotnet-interop/wasm-browser-app?view=aspnetcore-8.0)

Bài viết này giải thích cách thiết lập dự án WebAssembly Browser App để chạy .NET từ JavaScript (JS) sử dụng JS [JSImport]/[JSExport] interop. Để biết thêm thông tin và ví dụ, xem JavaScript [JSImport]/[JSExport] interop trong .NET WebAssembly.

Để biết thêm hướng dẫn, xem hướng dẫn Configuring and hosting .NET WebAssembly applications trong repository GitHub .NET Runtime (dotnet/runtime).

Các ứng dụng JS hiện có có thể sử dụng hỗ trợ WebAssembly phía client mở rộng để tái sử dụng thư viện .NET từ JS hoặc để xây dựng các ứng dụng và framework mới dựa trên .NET.

Lưu ý: Bài viết này tập trung vào việc chạy .NET từ các ứng dụng JS mà không có bất kỳ phụ thuộc nào vào Blazor. Để biết hướng dẫn về việc sử dụng [JSImport]/[JSExport] interop trong Blazor WebAssembly, xem JavaScript JSImport/JSExport interop với ASP.NET Core Blazor.

Điều kiện tiên quyết

.NET SDK (phiên bản mới nhất)

Cài đặt workload wasm-tools trong command shell quản trị, đưa vào các MSBuild target liên quan:

dotnetcli
dotnet workload install wasm-tools

Các công cụ cũng có thể được cài đặt thông qua Visual Studio Installer trong workload ASP.NET and web development. Chọn tùy chọn .NET WebAssembly build tools từ danh sách các thành phần tùy chọn.

Tùy chọn, cài đặt workload wasm-experimental, thêm các project template (mẫu dự án) thử nghiệm sau:

dotnetcli
dotnet workload install wasm-experimental

Các template cũng có thể được cài đặt từ gói NuGet Microsoft.NET.Runtime.WebAssembly.Templates với lệnh sau:

dotnetcli
dotnet new install Microsoft.NET.Runtime.WebAssembly.Templates

Namespace (Không gian tên)

API JS interop được mô tả trong bài viết này được kiểm soát bởi các thuộc tính trong namespace System.Runtime.InteropServices.JavaScript.

Cấu hình dự án

Để cấu hình dự án (.csproj) để kích hoạt JS interop:

``xml <TargetFramework>{TARGET FRAMEWORK}</TargetFramework> ``

.NET 7 (net7.0) hoặc mới hơn được hỗ trợ.

``xml <AllowUnsafeBlocks>true</AllowUnsafeBlocks> ``

> Cảnh báo: API JS interop yêu cầu kích hoạt AllowUnsafeBlocks. Hãy cẩn thận khi triển khai code unsafe (không an toàn) của riêng bạn trong các ứng dụng .NET, vì điều này có thể giới thiệu các rủi ro bảo mật và ổn định.

Ví dụ file dự án (.csproj) sau cấu hình (placeholder {TARGET FRAMEWORK} là target framework):

xml
<Project Sdk="Microsoft.NET.Sdk.WebAssembly">

  <PropertyGroup>
    <TargetFramework>{TARGET FRAMEWORK}</TargetFramework>
    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
  </PropertyGroup>

</Project>

JavaScript interop trên WASM

Các API trong ví dụ sau được nhập từ dotnet.js. Các API này cho phép bạn thiết lập các module có tên có thể được nhập vào code C# và gọi các phương thức được công khai bởi code .NET, bao gồm Program.Main.

Quan trọng: "Import" (nhập) và "export" (xuất) trong bài viết này được định nghĩa từ góc nhìn của .NET: - Ứng dụng import các phương thức JS để chúng có thể được gọi từ .NET. - Ứng dụng export các phương thức .NET để chúng có thể được gọi từ JS.

Trong ví dụ sau:

Module JS (cho ASP.NET Core 8.0):

javascript
import { dotnet } from './_framework/dotnet.js'

const { setModuleImports, getAssemblyExports, getConfig } = await dotnet
  .withDiagnosticTracing(false)
  .withApplicationArgumentsFromQuery()
  .create();

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);

document.getElementById('out').innerHTML = text;
await dotnet.run();

Để nhập một hàm JS để nó có thể được gọi từ C#, sử dụng JSImportAttribute trên chữ ký phương thức phù hợp. Tham số đầu tiên của JSImportAttribute là tên của hàm JS cần nhập và tham số thứ hai là tên của module.

Trong ví dụ sau, hàm window.location.href được gọi từ module main.js khi phương thức GetHRef được gọi:

csharp
[JSImport("window.location.href", "main.js")]
internal static partial string GetHRef();

Trong chữ ký phương thức được nhập, bạn có thể sử dụng các kiểu .NET cho tham số và giá trị trả về, được marshalled tự động bởi runtime.

Các hàm có thể truy cập trên namespace toàn cục có thể được nhập bằng cách sử dụng tiền tố globalThis trong tên hàm và sử dụng thuộc tính [JSImport] mà không cần tên module:

csharp
[JSImport("globalThis.console.log")]
internal static partial void Log([JSMarshalAs<JSType.String>] string message);

Để export một phương thức .NET để nó có thể được gọi từ JS, sử dụng JSExportAttribute:

csharp
[JSExport]
internal static string Greeting()
{
    var text = $"Hello, World! Greetings from {GetHRef()}";
    Console.WriteLine(text);
    return text;
}

Workload thử nghiệm và project template

Để minh họa chức năng JS interop và lấy các project template JS interop, cài đặt workload wasm-experimental:

dotnetcli
dotnet workload install wasm-experimental

Workload wasm-experimental chứa hai project template: wasmbrowserwasmconsole. Những template này đang ở giai đoạn thử nghiệm tại thời điểm này, nghĩa là developer workflow cho các template đang được phát triển. Tuy nhiên, các API .NET và JS được sử dụng trong các template được hỗ trợ trong .NET 8 và cung cấp nền tảng để sử dụng .NET trên WASM từ JS.

Các template cũng có thể được cài đặt từ gói NuGet Microsoft.NET.Runtime.WebAssembly.Templates:

dotnetcli
dotnet new install Microsoft.NET.Runtime.WebAssembly.Templates

Ứng dụng trình duyệt (Browser app)

Bạn có thể tạo một ứng dụng trình duyệt với template wasmbrowser từ dòng lệnh, tạo ra một ứng dụng web minh họa sử dụng .NET và JS cùng nhau trong trình duyệt:

dotnetcli
dotnet new wasmbrowser

Ngoài ra trong Visual Studio, bạn có thể tạo ứng dụng sử dụng project template WebAssembly Browser App.

Build ứng dụng từ Visual Studio hoặc sử dụng .NET CLI:

dotnetcli
dotnet build

Build và chạy ứng dụng từ Visual Studio hoặc sử dụng .NET CLI:

dotnetcli
dotnet run

Ngoài ra, cài đặt và sử dụng lệnh dotnet serve:

dotnetcli
dotnet serve -d:bin/$(Configuration)/{TARGET FRAMEWORK}/publish

Ứng dụng console Node.js

Bạn có thể tạo ứng dụng console với template wasmconsole, tạo ra ứng dụng chạy dưới WASM như ứng dụng console Node.js hoặc V8:

dotnetcli
dotnet new wasmconsole

Ngoài ra trong Visual Studio, bạn có thể tạo ứng dụng sử dụng project template WebAssembly Console App.

Build ứng dụng:

dotnetcli
dotnet build

Build và chạy ứng dụng:

dotnetcli
dotnet run

Ngoài ra, khởi động bất kỳ static file server nào từ thư mục output publish chứa file main.mjs:

code
node bin/$(Configuration)/{TARGET FRAMEWORK}/{PATH}/main.mjs

Trong đó {TARGET FRAMEWORK} là target framework moniker và {PATH} là đường dẫn đến file main.mjs.