You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 21:45:17