Blazor项目用LibMan安装Bootstrap、Popper、jQuery遇问题求助
我正在开发Blazor项目,使用Bootstrap的工具提示和弹出框功能,这些功能依赖jQuery和Popper。
背景
最初手动下载了jQuery、Popper、Bootstrap的css和js文件,放在wwwroot/css和wwwroot/js目录,结构如下:
/wwwroot | |- css/ | | | |- bootstrap/ | | | `- site.css | |- images/ | `- js/ | |- bootstrap/ | |- jquery/ | |- popper/ | |- BootstrapJavascript.js | `- JavaScript.js
此时应用运行完全正常。
后来改用LibMan自动化安装依赖,操作路径:Solution Explorer -> Project -> Add -> Client-Side Library...,安装后wwwroot结构变为:
/wwwroot | |- css/ | | | |- bootstrap*.* | | | `- site.css | |- images/ | |- js/ | | | |- bootstrap*.* | | | |- cjs/ | | | |- esm/ | | | |- umd/ | | | `- BootstrapJavascript.js | `- scss/
同时,我将Bootstrap官网提供的启用工具提示和弹出框的代码放入BootstrapJavascript.js:
// 启用Bootstrap工具提示 const tooltipTriggerList = document.querySelectorAll('[data-bs-toggle="tooltip"]') const tooltipList = [...tooltipTriggerList].map(tooltipTriggerEl => new bootstrap.Tooltip(tooltipTriggerEl)) // 启用Bootstrap弹出框 const popoverTriggerList = document.querySelectorAll('[data-bs-toggle="popover"]') const popoverList = [...popoverTriggerList].map(popoverTriggerEl => new bootstrap.Popover(popoverTriggerEl))
问题现象
改用LibMan后应用报错,提示找不到库或组件,其中一个关键错误:
ReferenceError: exports is not defined at https://localhost:5003/js/cjs/popper.js:7:23
错误出现在App.razor第48行,对应代码:
protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { await JSRuntime.InvokeAsync<IJSObjectReference>("import", "/js/cjs/popper.js"); // 错误行 await JSRuntime.InvokeAsync<IJSObjectReference>("import", "/js/bootstrap.js"); await JSRuntime.InvokeAsync<IJSObjectReference>("import", "/js/BootstrapJavaScript.js"); } }
补充配置
libman.json
{ "version": "1.0", "defaultProvider": "cdnjs", "libraries": [ { "library": "jquery@3.6.1", "destination": "wwwroot/js/jquery/" }, { "library": "popper.js@2.11.6", "destination": "wwwroot/js/popper/" }, { "library": "twitter-bootstrap@5.2.2", "destination": "wwwroot/" } ] }
修改后的App.razor
protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { await JSRuntime.InvokeAsync<IJSObjectReference>("import", "/js/jquery/jquery.min.js"); await JSRuntime.InvokeAsync<IJSObjectReference>("import", "/js/popper/cjs/popper.min.js"); await JSRuntime.InvokeAsync<IJSObjectReference>("import", "/js/bootstrap.min.js"); await JSRuntime.InvokeAsync<IJSObjectReference>("import", "/js/BootstrapJavaScript.js"); } }
_Host.cshtml
<head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <base href="~/" /> <link rel="stylesheet" href="~/css/bootstrap.css" /> <link rel="stylesheet" href="~/css/site.css" /> </head> ... </div> <script> var blackpearlScript = document.createElement('script'); blackpearlScript.setAttribute('src', '/js/JavaScript.js'); document.head.appendChild(blackpearlScript); </script> </body>
1. 切换Popper的引入版本
报错核心原因是引入了Popper的CJS(CommonJS)版本,该版本适配Node.js环境,浏览器需使用UMD版本。修改App.razor中的Popper路径:
await JSRuntime.InvokeAsync<IJSObjectReference>("import", "/js/popper/umd/popper.min.js");
2. 优化LibMan配置,对齐手动安装的文件结构
当前Bootstrap安装后文件直接放在wwwroot根目录,导致结构混乱。修改libman.json中Bootstrap的配置,只下载需要的css和js文件:
{ "library": "twitter-bootstrap@5.2.2", "destination": "wwwroot/", "files": [ "css/bootstrap.min.css", "js/bootstrap.min.js" ] }
执行LibMan还原后,wwwroot/css和wwwroot/js的结构将与手动安装时一致,避免多余的scss等文件干扰。
3. 调整脚本加载方式(可选)
Blazor中动态导入脚本可能存在顺序问题,建议直接在_Host.cshtml中通过<script>标签按依赖顺序加载:
<body> ... <script src="~/js/jquery/jquery.min.js"></script> <script src="~/js/popper/umd/popper.min.js"></script> <script src="~/js/bootstrap.min.js"></script> <script src="~/js/BootstrapJavaScript.js"></script> <script> var blackpearlScript = document.createElement('script'); blackpearlScript.setAttribute('src', '/js/JavaScript.js'); document.head.appendChild(blackpearlScript); </script> </body>
若采用此方式,需删除App.razor中OnAfterRenderAsync里的脚本导入代码。
4. 验证最终文件结构
确保wwwroot/js结构与手动安装时一致:
/js/ | |- jquery/ | `- jquery.min.js | |- popper/ | `- umd/ | `- popper.min.js | |- bootstrap.min.js | |- BootstrapJavascript.js | `- JavaScript.js
内容的提问来源于stack exchange,提问作者Brian

