如何将 vite 与“新”.net 7 Web 程序集项目一起使用

How do I use vite with the "new" .net 7 web assembly project

提问人:Nikolay 提问时间:10/23/2023 最后编辑:Nikolay 更新时间:10/29/2023 访问量:35

问:

我正在构建一个客户端应用程序(使用 html/javascript),并希望在其中使用一个使用 .net 7 编译的 Web 程序集。

https://learn.microsoft.com/en-us/aspnet/core/client-side/dotnet-interop

https://www.meziantou.net/using-dotnet-code-from-javascript-using-webassembly.htm

该应用程序未使用 blazor,它是一个普通的基于 React vite 的应用程序。因此,我从 dotent 中得到了这个 dotnet.js 文件和一堆其他文件(AppBundle 文件夹),现在我想从我的 Vite 应用程序中的一些 React 组件中使用它。那么我该怎么做呢?

如果我尝试直接这样做:

import { dotnet } = from '../../wasm/bin/Release/net7.0/browser-wasm/AppBundle/dotnet.js';

// then use use dotent

然后它甚至可以在调试中工作,但是在捆绑时,vite 会哭泣动态导入,并且无法正确打包 AppBundle,从而留下 .dll 和其他东西。此外,不喜欢重命名为 ,并且只是中断。另外,vite 重命名为 ,也许这是 dotnet 部分不喜欢的。dotent.jsdotnet.123ak.jsdotnet.wasmdotnet.123ak.wasm

无论如何。拥有某种“虚拟”(未处理)导入就足够了,我可以以某种方式指定将其解析为“dotent.js”文件,强制解析为某个固定路径(外部)。如何使用 vite 实现这一点?即基本上,我想要

  • 我的项目要编译,即编译时不会出现错误。
  • 输出文件(例如,page.tsx => page.js)来引用某些特定的固定路径,例如“/AppBundle/dotnet.js”。举个例子:

如果我像这样导入:

import { dotnet } from 'some-file'

然后在构建时我没有收到任何错误,并且在构建后我被替换为(配置中的固定值)some-file/MyAppBundle/dotnet.js

我怎样才能做到这一点(例如,使用 webpack,配置中有“解决”选项,也许在 vite 中有类似的东西可以帮助?

javascript vite webassembly net-7.0

评论


答:

0赞 Nikolay 10/29/2023 #1

想通了。您可以使用它来工作。写了一篇关于这个的帖子:await import(...)

https://medium.com/@nbelyh/using-net-as-a-webassembly-from-javascript-react-16fd9373c411

用法

  const { dotnet, loading } = 
     useDotNet('/path/to/your/AppBundle/dotnet.js')

定义

import { useEffect, useRef, useState } from 'react';

export const useDotNet = (url: string) => {

  const dotnetUrl = useRef('');
  const [dotnet, setDotNet] = useState<any>(null);
  const [loading, setLoading] = useState(true);

  const load = async (currentUrl: string): Promise<any> => {

    const module = await import(/* @vite-ignore */ currentUrl);

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

    const config = getConfig();
    const exports = await getAssemblyExports(config.mainAssemblyName);
    return exports;
  }

  useEffect(() => {
    if (dotnetUrl.current !== url) { // safeguard to prevent double-loading
      setLoading(true);
      dotnetUrl.current = url;
      load(url)
        .then(exports => setDotNet(exports))
        .finally(() => setLoading(false))
    }
  }, [url]);
  return { dotnet, loading };
}