需要Blazor和LibMan的协助以安装Bootstrap和相关组件(即Popper和jQuery)

ukqbszuj  于 2022-12-07  发布在  Bootstrap
关注(0)|答案(2)|浏览(156)

I am working on a Blazor project in which I am using Bootstrap; which, of course, requires jQuery and Popper for the tooltips and popovers to work.
Originally, I just "manually" downloaded the required files:

  • jQuery
  • Popper
  • Bootstrap (css and js)

and put them where they need to go:

  • wwwroot/css
  • wwwroot/js

The structure of wwwroot looked like this:

/wwwroot
|
|- css/
|  |
|  |- bootstrap/
|  |
|  `- site.css
|
|- images/
|
`- js/
   |
   |- bootstrap/
   |
   |- jquery/
   |
   |- popper/
   |
   |- BootstrapJavascript.js
   |
   `- JavaScript.js

However, the "powers that be" have decided they would like to make this more efficient and automatic, so I now need to use LibMan to install everything, and I am using this method:

Solution Explorer -> Project -> Add -> Client-Side Library...

So, everything went smoothly when installing, however I am having trouble with Popper. After installing, wwwroot now looks like this:

/wwwroot
|
|- css/
|  |
|  |- bootstrap*.*
|  |
|  `- site.css
|
|- images/
|
|- js/
|  |
|  |- bootstrap*.*
|  |
|  |- cjs/
|  |
|  |- esm/
|  |
|  |- umd/
|  |
|  `- BootstrapJavascript.js
|
`- scss/

And I am receiving errors indicating that the application cannot find certain libraries or components of libraries.
Originally, when using LibMan to install Popper, LibMan wanted to put Popper here:

wwwroot/lib/popper.js/

However, I elected to put Popper in:

wwwroot/js/

Also, on Bootstraps website, they instruct to pre-load the ability to use tooltips and popovers like this:

// For Bootstrap's Tooltips
// https://getbootstrap.com/docs/5.2/components/tooltips/
const tooltipTriggerList = document.querySelectorAll('[data-bs-toggle="tooltip"]')
const tooltipList = [...tooltipTriggerList].map(tooltipTriggerEl => new bootstrap.Tooltip(tooltipTriggerEl))

// For Bootstrap's Popovers
// https://getbootstrap.com/docs/5.2/components/popovers/
const popoverTriggerList = document.querySelectorAll('[data-bs-toggle="popover"]')
const popoverList = [...popoverTriggerList].map(popoverTriggerEl => new bootstrap.Popover(popoverTriggerEl))

Which I have in my BootstrapJavascript.js file.
Some of the errors I am getting:

ReferenceError: exports is not defined
    at https://localhost:5003/js/cjs/popper.js:7:23

Error at App.razor:line 48 , which is in here:

protected override async Task OnAfterRenderAsync(bool firstRender)
{
    if (firstRender)
    {
        await JSRuntime.InvokeAsync<IJSObjectReference>("import", "/js/cjs/popper.js"); // THIS IS LINE #48
        await JSRuntime.InvokeAsync<IJSObjectReference>("import", "/js/bootstrap.js");
        await JSRuntime.InvokeAsync<IJSObjectReference>("import", "/js/BootstrapJavaScript.js");
    }
}

The application was working "perfectly" when I was hand installing Bootstrap, Popper, and jQuery, now it is not.
What do I need to do to get this working like when I was hand-installing?

EDIT:
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>
isr3a4wc

isr3a4wc1#

首先,我不知道你为什么把js文件放在App.razor中,我认为最好把它们放在MainLayout.razor_Host.cshtml中:

<script src="~/lib/jquery/jquery.min.js"></script>

其次,我认为您不需要包含Popper,因为Bootstrap在bootstrap.bundle.js中已经有此库,请参见link。您可以按如下方式添加此文件:

解决方案资源管理器-〉右击项目-〉添加-〉客户端库-〉twitter-bootstrap -〉选择特定文件-〉js -〉bootstrap.bundle.min.js。

请注意这些文件将被添加到lib文件夹中,如果您想更改位置,则需要更改您的libman.json,我认为没有必要更改位置,只需将它们保存在lib文件夹中即可。
MainLayout.razor_Host.cshtml中的脚本将为:

<script src="~/lib/jquery/jquery.min.js"></script>
<script src="~/lib/twitter-bootstrap/js/bootstrap.bundle.min.js"></script>
<script src="~/js/BootstrapJavaScript.js"></script>
hk8txs48

hk8txs482#

我试着充分解释我在项目中使用的一般解决方案。可能,你的问题是在js和css条目的定义上。
首先使用以下命令安装LibMan

dotnet tool install -g Microsoft.Web.LibraryManager.Cli

下一步是在项目中添加一个名为libman.json的文件。

libman init

正如您所看到的,我们还可以指定包接收源,默认情况下设置为cdnjs,实际上是一个内容交付网络(CDN),用于无数的客户端包。我们还可以在库数组中输入所需的包。什至对于每个包,我们都可以覆盖提供程序。

`{"version": "1.0",
  "defaultProvider": "cdnjs",
  "libraries": [

  ]
}`

现在,您可以通过以下命令获取Jquery、Bootstrap等:

libman install bootstrap --provider unpkg --destination wwwroot/lib/bootstrap
libman install jquery --provider unpkg --destination wwwroot/lib/jquery

最后,libman.json文件将具有以下结构:

`{"version": "1.0",
  "defaultProvider": "",
  "libraries": [
 {
  "provider": "cdnjs",
  "library": "twitter-bootstrap@5.1.3",
  "destination": "wwwroot/lib/twitter-bootstrap/"
},    
{
  "provider": "unpkg",
  "library": "jquery@3.6.0",
  "destination": "wwwroot/lib/jquery/"
}
  ]
}`

收到客户端软件包后,我们将把相关条目添加到Blazor Server应用程序的Pages \_Layout.cshtml文件(或Blazor WASM应用程序的wwwroot/index.html文件)。

<head>
        <base href="~/" />      
        <link rel="stylesheet" href="lib/twitter- 
            bootstrap/css/bootstrap.min.css" />
    </head>
    <body>
        ..........
        ..........
        <script src="lib/jquery/dist/jquery.min.js"></script>        
        <script src="_framework/blazor.server.js"></script>
    </body>

我们在head部分定义了css文件的入口,在body标签结束之前定义了js文件的入口,当然在Blazor Server中也是在<script src="_framework/blazor.server.js"></script>之前定义的,wwwroot起始文件夹就不用说了;因为定义了base href,所以它指向此文件夹。
您还可以使用libman restore命令重新安装软件包;在这种情况下,就像Nuget一样,包将从相关提供者的libman.json文件中下载并添加到项目中。
还有一点:您可以按如下所示修改程序的csproj文件,以便在生成之前自动运行libman restore命令:

<Project Sdk="Microsoft.NET.Sdk.Web">

      <PropertyGroup>
        <TargetFramework>net5.0</TargetFramework>
      </PropertyGroup>

      <Target Name="DebugEnsureLibManEnv" BeforeTargets="BeforeBuild" Condition=" '$(Configuration)' == 'Debug' ">
        <!-- Ensure libman is installed -->
        <Exec Command="libman --version" ContinueOnError="true">
          <Output TaskParameter="ExitCode" PropertyName="ErrorCode" />
        </Exec>
        <Error Condition="'$(ErrorCode)' != '0'" Text="libman is required to build and run this project. To continue, please run `dotnet tool install -g Microsoft.Web.LibraryManager.Cli`, and then restart your command prompt or IDE." />
        <Message Importance="high" Text="Restoring dependencies using 'libman'. This may take several minutes..." />
        <Exec WorkingDirectory="$(MSBuildProjectDirectory)" Command="libman restore" />
      </Target>
    </Project>

编辑:

根据您的评论和编辑的问题:
首先, Bootstrap 包安装在wwwroot的根目录中。

{
  "library": "twitter-bootstrap@5.2.2",
  "destination": "wwwroot/"
}

但是,它在JS文件夹中被引用。

await JSRuntime.InvokeAsync<IJSObjectReference>("import", "/js/bootstrap.min.js");

其次,请从_Host.cshtml中删除下面的行:

<link rel="stylesheet" href="~/css/bootstrap.css" />

我建议您尝试引用_Host.cshtml文件而不是引用OnAfterRenderAsync方法,如下所示:

<link rel="stylesheet" href="twitter-bootstrap/css/bootstrap.min.css" />

您可以对其他库(如Popper)执行相同的操作。
最初,在使用LibMan安装Popper时,LibMan希望将Popper放在此处
也请试试这个。它表示默认安装路径(/lib)在libman文件夹中。
我认为现在运行的我的项目的代码和你的项目的代码之间的所有区别都是这些东西。

相关问题