I'm just starting in blazer, trying to write a webpage with wasm. I was having trouble including 3rd party javascript libraries (it seemed like they were getting run twice) and I've simplified the issue to this simple example. Here is the entire content of Map.razor:
@page "/map"
@rendermode InteractiveWebAssembly
<script>
console.log("starting");
const myConstant = 2;
</script>
When I run this and navigate to https://localhost:7028/map in my browser, I get an error in the console: "Uncaught SyntaxError: redeclaration of const myConstant". I've looked at the page-source in the browser and confirmed that there is only one instance of this script tag. I thought the behavior could be re-rendering related so I added some debugging code:
@page "/map"
@rendermode InteractiveWebAssembly
<script>
console.log("starting");
const myConstant2 = 1;
</script>
@code {
protected override async Task OnInitializedAsync()
{
Console.WriteLine("Initialized");
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
Console.WriteLine("rendereding");
}
}
And the output is as I expect (only says "Initialized", "rendereding", and "starting" once). If I change my tags to reference a source file instead of having the javascript inline, the network tab in the browser developer window shows that the script is being fetched twice, once at the beginning, and then again after a half-second delay. And it still gets run twice (error on constant being already defined, or repeats of console.log messages).
@page "/map"
@rendermode InteractiveWebAssembly
<script src="/js/MapBehavior.js"></script>
@code {
protected override async Task OnInitializedAsync()
{
Console.WriteLine("Initialized");
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
Console.WriteLine("rendereding");
}
}
Where MapBehavior.js has:
console.log("loading MapBehavior.js");
const myConstant = 1;
console.log("defined constant in MapBehavior.js");
console.log("loaded mapBehavior.js");
And the console output is:
loading MapBehavior.js MapBehavior.js:7:9
defined constant in MapBehavior.js MapBehavior.js:9:9
loaded mapBehavior.js MapBehavior.js:401:9
CSS Hot Reload ignoring https://localhost:7028/bootstrap/bootstrap.min.css because it was inaccessible or had more than 7000 rules. browserLink:50:1248
dotnet Loaded 8.50 MB resources
This application was built with linking (tree shaking) disabled.
Published applications will be significantly smaller if you install wasm-tools workload.
See also https://aka.ms/dotnet-wasm-features assetsCache.ts:30:12
Debugging hotkey: Shift+Alt+D (when application has focus) blazor.web.js:1:154576
Initialized blazor.web.js:1:157717
rendereding blazor.web.js:1:157717
Uncaught SyntaxError: redeclaration of const myConstant
<anonymous> https://localhost:7028/js/MapBehavior.js:1
I've seen this issue with firefox, chrome, and edge. I've done a fresh install of VisualStudio but maybe it saved some errant setting from a previous install. I've disabled hot-reload during debugging, no effect.
Why are my script tags being run twice by browsers?
It is rendered twice because of prerender. If you want to disable the prerender you could use
@rendermode @(new InteractiveWebAssemblyRenderMode(false))
But disable prerender means the page will render slowly waiting for WASM resources are downloaded. You could conditionally not run script in prerender like
@using System.Runtime.InteropServices
@rendermode InteractiveWebAssembly
@if (RuntimeInformation.ProcessArchitecture == Architecture.Wasm)
{
<script>
console.log("starting");
const myConstant = 2;
</script>
}