MVC4捆绑CSS失败意外令牌,发现'@import'

Kyl*_*yle 51 c# asp.net-mvc bundle asp.net-optimization

我正在尝试使用捆绑来组合和缩小一些CSS文件.在我的Global.aspx.cs中,Application_Start我有以下内容:

    var jsBundle = new Bundle("~/JSBundle", new JsMinify());
    jsBundle.AddDirectory("~/Scripts/", "*.js", false);
    jsBundle.AddFile("~/Scripts/KendoUI/jquery.min.js");
    jsBundle.AddFile("~/Scripts/KendoUI/kendo.web.min.js");
    BundleTable.Bundles.Add(jsBundle);

    var cssBundle = new Bundle("~/CSSBundle", new CssMinify());
    cssBundle.AddDirectory("~/Content/", "*.css", false);
    cssBundle.AddDirectory("~/Content/themes/base/", "*.css", false);
    cssBundle.AddFile("~/Styles/KendoUI/kendo.common.min.css");
    cssBundle.AddFile("~/Styles/KendoUI/kendo.default.min.css");
    BundleTable.Bundles.Add(cssBundle);
Run Code Online (Sandbox Code Playgroud)

在我的.cshtml文件中,我有以下内容:

<link href="/CSSBundle" rel="stylesheet" type="text/css" />
<script src="/JSBundle" type="text/javascript"></script>
Run Code Online (Sandbox Code Playgroud)

但是,当我查看我的bundle CSS文件的源代码时,它具有以下内容:

/* Minification failed. Returning unminified contents.
(40,1): run-time error CSS1019: Unexpected token, found '@import'
(40,9): run-time error CSS1019: Unexpected token, found '"jquery.ui.base.css"'
Run Code Online (Sandbox Code Playgroud)

......还有更多

关于如何解决这个问题的任何想法?

我确实将它缩小到以下行:

cssBundle.AddDirectory("~/Content/themes/base/", "*.css", false);
Run Code Online (Sandbox Code Playgroud)

如果我只有那行代码,我会得到相同的错误.

Hao*_*ung 47

这里有一些问题:

  1. css问题是由于包含了jquery.ui.all.css,因为默认的minifier不支持后续导入,这不是你想要做的事情,因为它会包含所有jquery ui css文件.所以你要做的不是使用*.css,而是明确列出你想要包含的jquery ui文件:

     bundles.Add(new StyleBundle("~/Content/themes/base/css").Include(
            "~/Content/themes/base/jquery.ui.core.css",
            "~/Content/themes/base/jquery.ui.resizable.css",
            "~/Content/themes/base/jquery.ui.selectable.css",
            "~/Content/themes/base/jquery.ui.accordion.css",
            "~/Content/themes/base/jquery.ui.autocomplete.css",
            "~/Content/themes/base/jquery.ui.button.css",
            "~/Content/themes/base/jquery.ui.dialog.css",
            "~/Content/themes/base/jquery.ui.slider.css",
            "~/Content/themes/base/jquery.ui.tabs.css",
            "~/Content/themes/base/jquery.ui.datepicker.css",
            "~/Content/themes/base/jquery.ui.progressbar.css",
            "~/Content/themes/base/jquery.ui.theme.css"));
    
    Run Code Online (Sandbox Code Playgroud)
  2. 其次,您希望使用Script/Styles.Render方法,而不是在执行时显式引用bundle url,因为在调试模式下,帮助程序将自动不捆绑/缩小并呈现对每个脚本/样式资产的单独引用,并且还会将捆绑内容的指纹附加到URL中,以便浏览器缓存可以正常工作.

    @Scripts.Render("~/JSBundle") and @Styles.Render("~/CSSBundle")
    
    Run Code Online (Sandbox Code Playgroud)
  3. 你也可以使用StyleBundle/ScriptBundle,它只是合成糖而不必传递新的Css/JsMinify.

您还可以查看本教程以获取更多信息: Bundling Tutorial

  • 你错过了"〜/ Content/themes/base/jquery.ui.menu.css"和"〜/ Content/themes/base/jquery.ui.spinner.css". (2认同)
  • 好吧,它遇到像@ -webkit-keyframes这样的东西时也无法捆绑,所以它不仅仅是在@import上失败. (2认同)

And*_*sko 10

或者你可以做的是为CssMinify编写自己的BundleTransform,当然你需要这样的灵活性.因此,例如,BundleConfig.cs中的代码如下所示:

using System;
using System.Web.Optimization;
using StyleBundle = MyNamespace.CustomStyleBundle;

public class BundleConfig
{
    public static void RegisterBundles(BundleCollection bundles)
    {
        bundles.Add(new StyleBundle("~/Content/themes/base/css")
            .IncludeDirectory("~/Content/themes/base", "*.css"));
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你需要添加的是:

public class CustomStyleBundle : Bundle
{
    public CustomStyleBundle(string virtualPath, IBundleTransform bundleTransform = null)
        : base(virtualPath, new IBundleTransform[1]
            {
                bundleTransform ?? new CustomCssMinify()
            })
    {
    }

    public CustomStyleBundle(string virtualPath, string cdnPath, IBundleTransform bundleTransform = null)
        : base(virtualPath, cdnPath, new IBundleTransform[1]
            {
                bundleTransform ?? new CustomCssMinify()
            })
    {
    }
}

public class CustomCssMinify : IBundleTransform
{
    private const string CssContentType = "text/css";

    static CustomCssMinify()
    {
    }

    public virtual void Process(BundleContext context, BundleResponse response)
    {
        if (context == null)
            throw new ArgumentNullException("context");
        if (response == null)
            throw new ArgumentNullException("response");
        if (!context.EnableInstrumentation)
        {
            var minifier = new Minifier();
            FixCustomCssErrors(response);
            string str = minifier.MinifyStyleSheet(response.Content, new CssSettings()
            {
                CommentMode = CssComment.None
            });
            if (minifier.ErrorList.Count > 0)
                GenerateErrorResponse(response, minifier.ErrorList);
            else
                response.Content = str;
        }
        response.ContentType = CssContentType;
    }

    /// <summary>
    /// Add some extra fixes here
    /// </summary>
    /// <param name="response">BundleResponse</param>
    private void FixCustomCssErrors(BundleResponse response)
    {
        response.Content = Regex.Replace(response.Content, @"@import[\s]+([^\r\n]*)[\;]", String.Empty, RegexOptions.IgnoreCase | RegexOptions.Multiline);
    }

    private static void GenerateErrorResponse(BundleResponse bundle, IEnumerable<object> errors)
    {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.Append("/* ");
        stringBuilder.Append("CSS Minify Error").Append("\r\n");
        foreach (object obj in errors)
            stringBuilder.Append(obj.ToString()).Append("\r\n");
        stringBuilder.Append(" */\r\n");
        stringBuilder.Append(bundle.Content);
        bundle.Content = stringBuilder.ToString();
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您需要更多修复/错误,可以在FixCustomCssErrors方法中扩展此逻辑.

  • 这个解决方案有效地从文件中删除所有`@ import`,对吗?这可能不会使页面渲染得很好. (4认同)