MVC4捆绑包 - 没有Twitter Bootstrap图标

21

在调试模式下运行我的MVC4应用程序(因此没有css/scripts最小化)运行正常。 一旦我不使用调试运行(css/scripts被最小化),我的Twitter Bootstrap图标就不会显示。 这里的另一个线程建议使用bundles.IgnoreList.Clear()。 但对我似乎不起作用。 我的BundleConfig.RegisterBundles(...)如下所示:

public static void RegisterBundles(BundleCollection bundles)
{
    bundles.IgnoreList.Clear();

    // Some JavaScript bundles only
    // ...

    bundles.Add(new StyleBundle("~/bundles/maincss").Include(
        "~/Content/bootstrap.css",
        "~/Content/bootstrap-responsive.css",
       "~/Content/my.css"));
    }
}

所有包都是使用Nuget安装的(正如我所说,在调试模式下它能够正常工作)。我的Content文件夹还包含两个bootstrap...css文件的缩小版本,但没有一个缩小版本的my.css。字形图标位于images子文件夹中。

我的_Layout.cshtml文件看起来像这样:

<head>
    ...
    @Styles.Render("~/bundles/maincss")
</head>

我应该补充说明,通过“非调试”模式,我指的是在Web.config文件中设置debug =“false”选项:

<compilation debug="false" targetFramework="4.5" />

有人知道为什么 Twitter Bootstrap 图标在“非调试”模式下不显示吗?

谢谢 Rob


这个问题也适用于Font-Awesome。 - Bart Verkoeijen
2个回答

39

由于我在移动设备上,因此回复比较简短,但稍后我会更新。

阅读此内容

长话短说,这与捆绑后相对路径被损坏有关。但好消息是最新的包库已解决了这个问题。

更新

为填补空白,本质上正在发生的是CSS文件具有指向资源(在此情况下是图标精灵)的相对路径。当处于调试模式时,文件会分别输出到页面上,因此引用保留不变(/Content/bootstrap.css 引用 images/glyphicons-halflings.png,从而形成完整路径 /Content/images/glyphicons-halflings.png)。然而,当取消调试时,文件会被捆绑,路径现在相对于您给包定义的虚拟路径。在上述情况下,您现在始于 /bundles/maincss,这导致出现错误的 /bundles/maincss/images/glyphicons-halflings.png 路径。

好消息是这是一个已解决的错误,并且自 Microsoft.AspNet.Web.Optimization v1.1.0 起,您现在拥有 CssRewriteUrlTransform,它将用其绝对路径替换CSS文件内的所有相对路径。这意味着无论您如何称呼该包,资源都将得到解决。

因此,要修复此问题,您可以简单地执行以下操作:

IItemTransform cssFixer = new CssRewriteUrlTransform();

bundles.Add(
    new StyleBundle("~/bundles/maincss")
        .Include("~/Content/bootstrap.css", cssFixer)
        .Include("~/Content/bootstrap-responsive.css", cssFixer)
        .Include("~/Content/my.css", cssFixer)
);

我唯一的顾虑是当你想要多个文件时这看起来有多丑陋,因此为了解决这个问题,你可以使用扩展方法简化它:

我的唯一担忧是当您需要多个文件时,这个看起来很丑陋,因此为了解决这个问题,您可以使用扩展方法简化它:

/// <summary>
/// Includes the specified <paramref name="virtualPaths"/> within the bundle and attached the
/// <see cref="System.Web.Optimization.CssRewriteUrlTransform"/> item transformer to each item
/// automatically.
/// </summary>
/// <param name="bundle">The bundle.</param>
/// <param name="virtualPaths">The virtual paths.</param>
/// <returns>Bundle.</returns>
/// <exception cref="System.ArgumentException">Only available to StyleBundle;bundle</exception>
/// <exception cref="System.ArgumentNullException">virtualPaths;Cannot be null or empty</exception>
public static Bundle IncludeWithCssRewriteTransform(this Bundle bundle, params String[] virtualPaths)
{
    if (!(bundle is StyleBundle))
    {
        throw new ArgumentException("Only available to StyleBundle", "bundle");
    }
    if (virtualPaths == null || virtualPaths.Length == 0)
    {
        throw new ArgumentNullException("virtualPaths", "Cannot be null or empty");
    }
    IItemTransform itemTransform = new CssRewriteUrlTransform();
    foreach (String virtualPath in virtualPaths)
    {
        if (!String.IsNullOrWhiteSpace(virtualPath))
        {
            bundle.Include(virtualPath, itemTransform);
        }
    }
    return bundle;
}

这使得上面的代码更加简洁。(可以说我选择了一个比较长的方法名称,但我喜欢让方法名称与其用途清晰明了)

bundles.Add(
    new StyleBundle("~/bundles/maincss").IncludeWithCssRewriteTransform(
        "~/Content/bootstrap.css",
        "~/Content/bootstrap-responsive.css",
        "~/Content/my.css"
    )
);

1
谢谢你提供的链接,它帮助我解决了问题。我按照以下方式更改了我的代码: bundles.Add(new StyleBundle("/Content/maincss").Include( "/Content/bootstrap.css", "/Content/bootstrap-responsive.css", "/Content/my.css")); 并且删除了 IgnoreList.Clear()。 现在它可以正常工作了。 - Rob L
@RobL:不需要更改bundle名称,只需要使用CssRewriteUrlTransform。我已经更新了我的答案,现在我用的是更好的键盘。;-) - Brad Christie
1
@BradChristie 很抱歉翻出了一篇旧帖子,也很抱歉我对这个问题的了解不够。你选择扩展Bundle并验证它是否为StyleBundle类型而不是仅仅扩展StyleBundle类,有特定的原因吗? - Colin Banbury
1
@colin:为了使其与现有的“.Include”方法流畅地配合使用,需要进行一些调整。否则,它只能在单独使用时起作用。 - Brad Christie
感谢您的澄清。 - Colin Banbury

10

我在使用Bootstrap 3.0时遇到了同样的问题。 @brad-christie 的答案 解决了我的问题,直到我使用NuGet升级到Microsoft ASP.Net Web优化框架1.1.1。这似乎使得CssRewriteUrlTransform修复无法正常工作。我通过删除对CssRewriteUrlTransform的引用并创建一个名为bootstrap-bundle-font-fix.css的样式表来解决问题,其中仅包含以下内容:

@font-face {
  font-family: 'Glyphicons Halflings';
  src: url('../../Content/fonts/glyphicons-halflings-regular.eot');
  src: url('../../Content/fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), 
       url('../../Content/fonts/glyphicons-halflings-regular.woff') format('woff'),
       url('../../Content/fonts/glyphicons-halflings-regular.ttf') format('truetype'), 
       url('../../Content/fonts/glyphicons-halflings-regular.svg#glyphicons-halflingsregular') format('svg');
}

然后将其包含在我的Bootstrap CSS捆绑包中:

bundles.Add(new StyleBundle("~/bundles/Content/bootstrap")
    .Include("~/Content/bootstrap/bootstrap.css")
    .Include("~/Content/bootstrap/bootstrap-theme.css")
    .Include("~/Content/bootstrap-bundle-font-fix.css")
    .Include("~/Content/sticky-footer-navbar.css"));

我遇到了类似的问题。我从NuGet获取了Microsoft.AspNet.Web.Optimization 1.1.3,但它似乎没有转换相对图像路径。发生了什么?有人破坏了CssRewriteUrlTransform吗? - Michael12345
5
成功了!我错过了两个问题。 1)如果存在*.min.css文件,则打包将使用其中的文件而不转换任何包含的URL。 2)一旦我删除*.min.css文件,就会进行转换,但由于虚拟文件夹,路径会混乱。通过遵循此问题得到解决:https://dev59.com/WWIj5IYBdhLWcg3w6JHU - Michael12345
谢谢你的解决方案,Michael。我也遇到了同样的问题。 - John Mc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接