web-dev-qa-db-fra.com

Échec du regroupement CSS MVC4 Échec du jeton inattendu, trouvé '@import'

J'essaie d'utiliser le regroupement pour combiner et réduire certains fichiers CSS. Dans mon Global.aspx.cs Application_Start J'ai les informations suivantes:

    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);

Et dans mon fichier .cshtml, j'ai les éléments suivants:

<link href="/CSSBundle" rel="stylesheet" type="text/css" />
<script src="/JSBundle" type="text/javascript"></script>

Cependant, lorsque je visualise la source de mon fichier CSS de bundles, il présente les éléments suivants:

/* 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"'

.... beaucoup plus

Des idées sur la façon de résoudre ce problème?

Je l'ai réduit à la ligne suivante:

cssBundle.AddDirectory("~/Content/themes/base/", "*.css", false);

Si je n'ai que cette ligne de code, j'obtiens les mêmes erreurs.

50
Kyle

Il y a quelques problèmes ici:

  1. Le problème css est dû à l'inclusion de jquery.ui.all.css, car le minifieur par défaut ne prend pas en charge les importations suivantes, et ce n'est pas ce que vous voulez faire de toute façon car il doublerait tous les fichiers jquery ui css. Donc, ce que vous voulez faire à la place, ce n'est pas utiliser * .css, et plutôt lister explicitement quels fichiers jquery ui vous voulez inclure:

     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"));
    
  2. Deuxièmement, vous souhaitez utiliser les méthodes Script/Styles.Render plutôt que de référencer explicitement l'url des bundles comme vous le faites, car les assistants ne regrouperont/ne réduiront pas automatiquement et ne rendront pas les références individuelles à chaque actif de script/style en mode débogage, et ajoutez également une empreinte digitale pour le contenu du bundle dans l'URL afin que la mise en cache du navigateur fonctionne correctement.

    @Scripts.Render("~/JSBundle") and @Styles.Render("~/CSSBundle")
    
  3. Vous pouvez également utiliser StyleBundle/ScriptBundle qui est juste du sucre syntaxique pour ne pas avoir à passer de nouveaux Css/JsMinify.

Vous pouvez également consulter ce tutoriel pour plus d'informations: Bundling Tutorial

47
Hao Kung

Ou ce que vous pouvez faire est d'écrire votre propre BundleTransform pour CssMinify si bien sûr vous avez besoin d'une telle flexibilité. Ainsi, par exemple, votre code dans BundleConfig.cs ressemble à:

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"));
    }
}

Ensuite, vous devez ajouter:

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();
    }
}

Et si vous avez besoin de quelques corrections/erreurs supplémentaires, vous pouvez étendre cette logique dans la méthode FixCustomCssErrors.

10
Andrey Borisko