Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to disable js/css validation when using System.Web.Optimization Bundling minimisation?

I am working with .NET 4.5 System.Web.Optimization bundling. When bundling files with minimisation turned on I have spotted that some CSS and JavaScript do not get minimised for not passing validation mechanisms. These files get messages written like

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

because class had font-family: @Arial Unicode MS;
or Javascript that didn't have window in front of global variable produced following errors.

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

I do understand that proper solution was to fix the errors, however having many files with lots of errors like these can be a hassle to fix sometimes. Is there a way to disable validation of css/js when bundling or one would have to use custom IBundleTransform writer that would remove things like "use strict" from javascript files that are being bundled and minified?

like image 475
Matas Vaitkevicius Avatar asked Aug 20 '14 11:08

Matas Vaitkevicius


1 Answers

You can accomplish this by writing your own class that inherits from IBundleBuilder.

The code below is an adaptation of a related NuGet package LicensedBundler, which preserves important comments and minifies files while not minifying files with errors, instead moving them and their error to the top of the bundle (the default functionality of the ASP.NET bundling is to not minify anything). As you can see, in the CssSettings there is an option to ignore all errors:

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

Then in your BundleConfig.cs, you use LicensedStyleBundle instead of StyleBundle:

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

You can do similar code for the ScriptBundle. If you need pointers, all the source code is at the Github project site for the NuGet package and would just need minor tweaks to ignore errors, like the above code does.

like image 131
MikeSmithDev Avatar answered Nov 09 '22 14:11

MikeSmithDev