如何在.NET WASM类库中嵌入JS互操作所需的JS文件?
我正在学习基于Microsoft.NET.Sdk.WebAssembly SDK的.NET WebAssembly应用(非Blazor)的JS互操作,已掌握使用[JSImport]特性绑定C#方法与JavaScript函数的基础,在Avalonia WASM应用中可正常运行——只需将JS文件放在正确位置并在HTML或main.js中引用即可。但现在我需要编写供WASM应用引用的类库,问题在于无法访问消费端WASM应用的wwwroot目录,目前只能让库的使用者手动将JS文件复制到其应用的wwwroot目录,这十分不便。我曾尝试让类库使用Microsoft.NET.Sdk.Razor SDK,理论上可将库的wwwroot内容同步到目标WASM应用的wwwroot,但在Avalonia WASM应用中尝试访问时出现404错误。请问是否存在通过MSBuild配置等方式,将JS文件嵌入类库,使其能被消费端WASM应用无缝加载的方法?
针对Avalonia WASM类库的JS文件无缝加载需求,有两种可靠方案:
方案一:通过MSBuild自动同步JS文件到消费端wwwroot
利用MSBuild的内容文件复制机制,让类库的JS文件在被引用时自动同步到消费端WASM应用的wwwroot目录,无需用户手动操作:
- 在类库项目中创建
wwwroot/js目录,将你的JS文件放入其中。 - 编辑类库的
.csproj文件,添加以下配置:
<ItemGroup> <!-- 将JS文件标记为带目标路径的内容文件 --> <ContentWithTargetPath Include="wwwroot\js\your-library.js"> <!-- 指定在消费端项目中的目标路径 --> <TargetPath>wwwroot\js\your-library.js</TargetPath> <!-- 发布时自动复制 --> <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory> <!-- 确保依赖项目能获取到该文件 --> <Private>True</Private> </ContentWithTargetPath> </ItemGroup>
当消费端WASM应用引用该类库后,构建或发布时,JS文件会自动被复制到消费端的wwwroot/js目录下,你可以在消费端的HTML或启动脚本中直接引用该路径。
方案二:将JS文件嵌入类库程序集,运行时动态注入
这种方案无需复制文件,直接把JS作为嵌入资源打包到类库程序集,在类库初始化时动态注入到浏览器页面:
- 在类库中创建
Resources目录,放入JS文件,然后编辑.csproj标记为嵌入资源:
<ItemGroup> <EmbeddedResource Include="Resources\your-library.js"> <!-- 指定资源的逻辑名称,用于后续读取 --> <LogicalName>YourLibraryNamespace.Resources.your-library.js</LogicalName> </EmbeddedResource> </ItemGroup>
- 在类库中添加初始化方法,读取嵌入资源并注入到页面:
using System.Reflection; using System.Text; using Avalonia.WebAssembly; namespace YourLibraryNamespace; public static class LibraryBootstrap { public static void Initialize() { var assembly = Assembly.GetExecutingAssembly(); // 对应上面设置的LogicalName var resourceName = "YourLibraryNamespace.Resources.your-library.js"; using var stream = assembly.GetManifestResourceStream(resourceName); using var reader = new StreamReader(stream, Encoding.UTF8); var jsCode = reader.ReadToEnd(); // 通过Avalonia的JS运行时执行注入JS代码 AvaloniaWebAssemblyPlatform.Instance.JSRuntime.InvokeVoid("eval", jsCode); } }
- 消费端WASM应用在启动时调用
LibraryBootstrap.Initialize()即可完成JS加载,之后就能正常使用[JSImport]绑定的方法。
关于Razor SDK无效的原因
Microsoft.NET.Sdk.Razor的wwwroot同步机制是专为Blazor应用设计的,其资源处理逻辑与Avalonia WASM不兼容,因此无法直接生效,建议使用上述两种方案替代。
内容的提问来源于stack exchange,提问作者Unknown Coder

