Closed elringus closed 2 years ago
I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.
I'd try doing the Remove
either in Directory.Build.targets (if the WasmNativeAsset item is normally added by a .targets file in a NuGet package) or in a custom target having AfterTargets= "LoadStaticWebAssetsBuildManifest"
(if that's what normally adds the item).
I'd try doing the
Remove
either in Directory.Build.targets (if the WasmNativeAsset item is normally added by a .targets file in a NuGet package) or in a custom target havingAfterTargets= "LoadStaticWebAssetsBuildManifest"
(if that's what normally adds the item).
Thanks for the advice! I've tried both:
<Target Name="RemoveBuiltinWasm" AfterTargets="LoadStaticWebAssetsBuildManifest">
<ItemGroup>
<WasmNativeAsset Remove="**/*.wasm"/>
</ItemGroup>
</Target>
and the same after PrepareForILLink
, as it should be there before the linking, but unfortunately it didn't help.
I've tried searching this repo hoping to find where it's actually added, but it looks like it's added somewhere else: https://github.com/dotnet/sdk/search?q=WasmNativeAsset
I've probably found where it's added: https://github.com/dotnet/runtime/blob/release/6.0/src/mono/wasm/build/WasmApp.targets#L257
But this is still producing the same error:
<Target Name="RemoveBuiltinModule" AfterTargets="_WasmBuildNative">
<ItemGroup>
<WasmNativeAsset Remove="**/*.wasm"/>
</ItemGroup>
</Target>
Oh, this
<WasmNativeAsset Remove="**/*.wasm"/>
I believe it searches for wasm files within your project directory and removes the corresponding WasmNativeAsset items. But if the items correspond to files that are outside your source tree, then they won't match and won't be removed. So you should instead use
<WasmNativeAsset Remove="@(WasmNativeAsset)" Condition="%(Extension) == '.wasm'"/>
which removes the existing items that have the .wasm
extension, regardless of what files exist.
You can also add %(Filename)
to the condition, to remove only dotnet.wasm while ignoring the drive and directory part of the path.
Thank you for the help! It no longer produce the error with the following:
<Target Name="RemoveBuiltinModule" AfterTargets="PrepareForILLink">
<ItemGroup>
<WasmNativeAsset Remove="@(WasmNativeAsset)" Condition="%(Extension) == '.wasm'"/>
</ItemGroup>
</Target>
<ItemGroup>
<WasmNativeAsset Include="../../runtime/artifacts/bin/native/net6.0-Browser-Release-wasm/dotnet.wasm"/>
</ItemGroup>
— but looks like now it ignores my custom wasm module and just uses the built-in one. Maybe it's overriding it at some point after...
The custom target looks like it will also remove your custom dotnet.wasm from WasmNativeAsset
. If you move the Include
into the target as well, that should fix it.
At this point though, it would be good to examine MSBuild logs and find out for certain what adds dotnet.wasm to WasmNativeAsset
. The _GetWasmGenerateAppBundleDependencies
target in WasmApp.targets cannot be the only one because it checks whether there is a dotnet.wasm item already and thus could not have added the duplicate item that caused an InvalidOperationException.
Thanks again, you're really helped me here! I've figured the following:
<Target Name="ReplaceWasm" AfterTargets="WasmTriggerPublishApp">
<ItemGroup>
<WasmNativeAsset Remove="@(WasmNativeAsset)" Condition="%(Extension) == '.wasm'"/>
<WasmNativeAsset Include="../../runtime/artifacts/bin/native/net6.0-Browser-Release-wasm/dotnet.wasm"/>
</ItemGroup>
</Target>
— works fine, it uses my module, but it seems to replace the module after trimming and AOT compilation steps. So when not using AOT the only downside is that the module is not trimmed (which is not a big deal), but when running the AOT, the custom module (which is just dotnet runtime) is replaced on top of the compiled module with all the project sources.
I'll dig deeper into msbuild logs and try to figure at which point to replace the module, so it's processed with the trimming and AOT.
The following replaces the wasm before it's used by the other targets:
<Target Name="ReplaceWasm" AfterTargets="WasmBuildApp">
<ItemGroup>
<WasmNativeAsset Remove="@(WasmNativeAsset)" Condition="%(Extension) == '.wasm'"/>
<WasmNativeAsset Include="../../runtime/artifacts/bin/native/net6.0-Browser-Release-wasm/dotnet.wasm"/>
</ItemGroup>
</Target>
— which is what I've been looking for. However, seems like I can't just provide a custom wasm and expect it to relink properly when trimming or AOTing, as it produce the following error when used:
failed to asynchronously prepare wasm: TypeError: WebAssembly.instantiate(): Import #0 module="a" error: module is not an object or function
TypeError: WebAssembly.instantiate(): Import #0 module="a" error: module is not an object or function
Though I guess this is out of scope for this repository. I'd appreciate if someone from the maintainers could verify that I'm replacing the wasm correctly and the behavior is expected, but otherwise the issue can be closed.
@Elringus thanks for contacting us.
This is not an scenario that we support. We would recommend you leverage the targets in the the .NET SDK directly rather than attaching to our targets in this way, as this is something that we might change in future releases.
Got it, thanks for the info!
Is it somehow possible to replace
dotnet.wasm
module which is referenced viaWasmNativeAsset
andWasmAotAssets
?I've built my own module from sources and need to use it instead of the one bundled with Sdk.BlazorWebAssembly.
I've tried adding the following in my csproj:
— but the build fails with:
I guess it fails to figure which module to use. I've tried removing the built-in one before adding my own:
— but it didn't help.