There is the following application called Fantastic Dice that is a javascript module. It can be loaded as such from the example provided here from this page.
=%2Fsrc%2Findex.js%3A1%2C1-2%2C1
I have tried doing this in a Blazor page with no success.
I have the following javascript file called dice.js
import DiceBox from "/@3d-dice/[email protected]/dist/dice-box.es.min.js";
export function DiceBoxCall() {
let Box = new DiceBox("#dice-box", {
assetPath: "assets/",
origin: "/@3d-dice/[email protected]/dist/",
theme: "default",
themeColor: "#feea03",
offscreen: true,
scale: 6
});
Box.init().then(async (world) => {
Box.roll(["4d20", "4d12", "4d10", "4d8", "4d6", "4d4"]);
});
}
I call it from Blazor using the JSRuntime library
await JSRuntime.InvokeVoidAsync("DiceBoxCall");
This loads, but It cannot find DiceBoxCall. I'm pretty sure its the import but that import is vital to everything. The library fantastic dice uses is an ESModule and the import call is loading the library into a class object. I cannot find any other example that would help me here.
Edit:
I tried using in the following way with no success.
<HeadContent>
<script type="module">
import DiceBox from "@3d-dice/dice-box"
</script>
</HeadContent>
There is the following application called Fantastic Dice that is a javascript module. It can be loaded as such from the example provided here from this page.
https://codesandbox.io/p/sandbox/dice-es6-module-cdn-lhbs99?file=%2Fsrc%2Findex.js%3A1%2C1-2%2C1
I have tried doing this in a Blazor page with no success.
I have the following javascript file called dice.js
import DiceBox from "https://unpkg/@3d-dice/[email protected]/dist/dice-box.es.min.js";
export function DiceBoxCall() {
let Box = new DiceBox("#dice-box", {
assetPath: "assets/",
origin: "https://unpkg/@3d-dice/[email protected]/dist/",
theme: "default",
themeColor: "#feea03",
offscreen: true,
scale: 6
});
Box.init().then(async (world) => {
Box.roll(["4d20", "4d12", "4d10", "4d8", "4d6", "4d4"]);
});
}
I call it from Blazor using the JSRuntime library
await JSRuntime.InvokeVoidAsync("DiceBoxCall");
This loads, but It cannot find DiceBoxCall. I'm pretty sure its the import but that import is vital to everything. The library fantastic dice uses is an ESModule and the import call is loading the library into a class object. I cannot find any other example that would help me here.
Edit:
I tried using in the following way with no success.
<HeadContent>
<script type="module">
import DiceBox from "@3d-dice/dice-box"
</script>
</HeadContent>
Share
Improve this question
edited Nov 25, 2024 at 9:14
Zhi Lv
22k1 gold badge27 silver badges37 bronze badges
asked Nov 17, 2024 at 17:05
DaveKDaveK
5901 gold badge7 silver badges21 bronze badges
5
- "you include the JavaScript in the HeadContent section of the Razor page and then add the module attribute" I have to be missing something then because I followed it as well which means there is something with Blazor and Javascript I am not understanding. Do you have an example of your what the <head> content looks like in including the javascript? I'm positive I have the JSRuntime correct. Just not how to get the Javascript included correctly. – DaveK Commented Nov 17, 2024 at 20:11
- 1 My project is Blazor Server .NET8 – DaveK Commented Nov 18, 2024 at 1:35
- 1 Interactive Server. Also the example code I have above is the code that comes from the CDN example. I have tried the documentation example as they have it written. The problem is obviously that import line they use to load a module. I tried <HeadContent> and that will not compile for me. I am using the example like you, but as you said you made "adjustments". I therefore must not understand how to successful load an ESModule into a blazor app. I would very much like to see how you loaded the module. – DaveK Commented Nov 18, 2024 at 12:38
- <HeadContent> will not compile for me. It says that "3d is not valid at the start of a code block. Only identifiers, keywords, comments, "(", and "{" are valid for the line for import. If I use the CDN version it still errors out. It doesn't like the @ symbol I suppose. – DaveK Commented Nov 18, 2024 at 20:47
- The example you provided does work, but it doesn't work in a way I need to work for me. The example I gave above is what I need because I would like to be able to reroll using JSRuntime so I can run other attributes. Thank you for the code, but in the end, what you gave me brings me right back to my original problem. – DaveK Commented Nov 19, 2024 at 0:25
1 Answer
Reset to default 1Just tried the approach similar to what I described in this post and it seems to be working.
I have three files:
- DiceRoller.razor page layout
@page "/DiceRoller"
<h3>DiceRoller</h3>
<div id="dice-box"></div>
- DiceRoller.razor.cs page code-behind (partial class)
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
namespace BlazorServerJS.Pages;
public partial class DiceRoller : ComponentBase
{
[Inject]
private IJSRuntime JS { get; set; } = default!;
private IJSObjectReference? _jsModule;
protected override async Task OnAfterRenderAsync(bool firstRender)
{
_jsModule ??= await JS.InvokeAsync<IJSObjectReference>(
"import", "./Pages/DiceRoller.razor.js");
await _jsModule.InvokeVoidAsync("DiceBoxCall");
await base.OnAfterRenderAsync(firstRender);
}
}
- DiceRoller.razor.js (just because I like to store .js and .css next to respective pages).
import DiceBox from "https://unpkg/@3d-dice/[email protected]/dist/dice-box.es.min.js";
export function DiceBoxCall() {
let Box = new DiceBox("#dice-box", {
assetPath: "assets/",
origin: "https://unpkg/@3d-dice/[email protected]/dist/",
theme: "default",
themeColor: "#feea03",
offscreen: true,
scale: 6
});
Box.init().then(async (world) => {
Box.roll(["4d20", "4d12", "4d10", "4d8", "4d6", "4d4"]);
});
}