Búsqueda de sitios web

c# - ¿Hay alguna manera de desactivar la validación de js/css al usar la minimización de Bundling de System.Web.Optimization?


Estoy trabajando con .NET 4.5 System.Web.Optimization bundling. Al agrupar archivos con la minimización activada, he notado que algunos CSS y JavaScript no se minimizan debido a que no pasan los mecanismos de validación. A estos archivos se les escriben mensajes como

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

porque la clase tenía font-family: @Arial Unicode MS;
o Javascript que no tenía window delante de la variable global produjo los siguientes errores.

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

Entiendo que la solución adecuada era corregir los errores, sin embargo, tener muchos archivos con muchos errores como estos puede ser una molestia de corregir a veces. ¿Hay alguna manera de desactivar la validación de css/js al agrupar o uno tendría que usar un escritor personalizado de IBundleTransform que elimine cosas como "use strict" de los archivos javascript que se están agrupando y minimizando?

Respuesta #1

Puedes lograr esto escribiendo tu propia clase que herede de IBundleBuilder.

El código a continuación es una adaptación de un paquete de NuGet relacionado, LicensedBundler, que preserva comentarios importantes y minimiza archivos mientras no minimiza archivos con errores, en su lugar mueve estos y su error al principio del paquete (la funcionalidad predeterminada del agrupamiento de ASP.NET es no minimizar nada). Como puede ver, en CssSettings hay una opción para ignorar todos los errores:

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

Luego, en tu BundleConfig.cs, usas LicensedStyleBundle en lugar de StyleBundle:

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

Puedes hacer un código similar para el ScriptBundle. Si necesitas orientación, todo el código fuente está en el sitio del proyecto de Github para el paquete NuGet y solo necesitaría ajustes menores para ignorar errores, como hace el código anterior.