Ricerca nel sito web

c# - C'è un modo per disabilitare la convalida js/css quando si utilizza la minimizzazione del bundle di System.Web.Optimization?


Sto lavorando con il bundling di .NET 4.5 System.Web.Optimization. Quando creo bundle di file con la minimizzazione attivata, ho notato che alcuni CSS e JavaScript non vengono minimizzati perché non superano i meccanismi di validazione. A questi file vengono scritti messaggi come

/* Minification failed. Returning unminified contents.
(5616,18): run-time error CSS1036: Expected expression, found '@Arial'

perché la classe aveva font-family: @Arial Unicode MS;
o Javascript che non aveva window davanti alla variabile globale produceva i seguenti errori.

/* Minification failed. Returning unminified contents.
(210,13-20): run-time error JS1300: Strict-mode does not allow assignment to undefined variables: PageObj
(189,13-20): run-time error JS1300: Strict-mode does not allow assignment to undefined variables: PageObj
 */

Capisco che la soluzione corretta fosse correggere gli errori, tuttavia avere molti file con così tanti errori può essere a volte difficile da sistemare. Esiste un modo per disattivare la validazione di CSS/JS durante il bundling o bisognerebbe utilizzare uno scrittore IBundleTransform personalizzato che rimuova elementi come "use strict" dai file JavaScript che vengono raggruppati e minimizzati?

Risposta n. 1

Puoi realizzare questo scrivendo la tua classe che eredita da IBundleBuilder.

Il codice qui sotto è un adattamento di un pacchetto NuGet correlato, LicensedBundler, che preserva i commenti importanti e minimizza i file senza minimizzare quelli con errori, spostandoli invece insieme al loro errore in cima al bundle (la funzionalità predefinita del bundling di ASP.NET è di non minimizzare nulla). Come puoi vedere, nelle CssSettings c'è un'opzione per ignorare tutti gli errori:

public class LicensedStyleBundle : Bundle
{
    public LicensedStyleBundle(string virtualPath)
        : base(virtualPath)
    {
        this.Builder = new LicencedStyleBuilder();
    }

    public LicensedStyleBundle(string virtualPath, string cdnPath)
        : base(virtualPath, cdnPath)
    {
        this.Builder = new LicencedStyleBuilder();
    }
}

public class LicencedStyleBuilder : IBundleBuilder
{
    public virtual string BuildBundleContent(Bundle bundle, BundleContext context, IEnumerable<BundleFile> files)
    {
        var content = new StringBuilder();
        foreach (var file in files)
        {
            FileInfo f = new FileInfo(HttpContext.Current.Server.MapPath(file.VirtualFile.VirtualPath));
            CssSettings settings = new CssSettings();
            settings.IgnoreAllErrors = true; //this is what you want
            settings.CommentMode = Microsoft.Ajax.Utilities.CssComment.Important;
            var minifier = new Microsoft.Ajax.Utilities.Minifier();
            string readFile = Read(f);
            string res = minifier.MinifyStyleSheet(readFile, settings);
            content.Append(res);
        }

        return content.ToString();
    }

    public static string Read(FileInfo file)
    {
        using (var r = file.OpenText())
        {
            return r.ReadToEnd();
        }
    }
}

Quindi, nel tuo BundleConfig.cs, usi LicensedStyleBundle invece di StyleBundle:

bundles.Add(new LicensedStyleBundle("~/Content/css").Include("~/Content/site.css"));

Puoi fare codice simile per lo ScriptBundle. Se hai bisogno di indicazioni, tutto il codice sorgente è sul sito del progetto Github per il pacchetto NuGet e richiederebbe solo piccole modifiche per ignorare gli errori, come fa il codice sopra.