如何在Blazor页面中调用依赖ESModule的JavaScript文件?
解决Blazor调用ES模块函数找不到的问题
核心原因
ES模块(type="module")的作用域仅限模块内部,导出的函数默认不会挂载到全局window对象上,而Blazor的JSRuntime是从全局作用域查找函数,因此直接调用会出现找不到的情况。
方法一:将函数挂载到全局对象
修改你的dice.js文件,在导出函数后把它挂载到window上,让全局作用域能访问到:
import DiceBox from "https://unpkg.com/@3d-dice/dice-box@1.0.8/dist/dice-box.es.min.js"; export function DiceBoxCall() { let Box = new DiceBox("#dice-box", { assetPath: "assets/", origin: "https://unpkg.com/@3d-dice/dice-box@1.0.8/dist/", theme: "default", themeColor: "#feea03", offscreen: true, scale: 6 }); Box.init().then(async (world) => { Box.roll(["4d20", "4d12", "4d10", "4d8", "4d6", "4d4"]); }); } // 将函数挂载到全局window对象 window.DiceBoxCall = DiceBoxCall;
然后在Blazor页面的HeadContent中引入这个模块脚本:
<HeadContent> <script type="module" src="~/dice.js"></script> </HeadContent>
之后执行你的C#代码即可正常调用:
await JSRuntime.InvokeVoidAsync("DiceBoxCall");
方法二:动态导入模块并调用(无需修改原JS文件)
如果不想修改原dice.js,可以在Blazor中通过动态导入的方式加载模块并调用函数,直接在InvokeVoidAsync中传入匿名函数:
await JSRuntime.InvokeVoidAsync(@"async () => { // 动态导入目标模块 const diceModule = await import('./dice.js'); // 调用模块导出的函数 diceModule.DiceBoxCall(); }");
这种方式不需要改动原JS文件结构,直接利用ES模块的动态导入特性获取函数并执行。
注意事项
- 确保
dice.js的路径正确:Blazor中~/指向wwwroot目录,若文件放在wwwroot下,路径就是~/dice.js。 - 动态导入时的路径要和页面的相对路径匹配,或使用绝对路径。
内容的提问来源于stack exchange,提问作者DaveK
相关产品推荐
相关产品推荐

