How to use ASP.Net MVC 4 to Bundle LESS files in Release mode?

Graham Clark picture Graham Clark · Mar 6, 2013 · Viewed 27.6k times · Source

I'm trying to have LESS files in my web project, and have the MVC 4 bundling functionality call into the dotLess library to turn the LESS into CSS, then minify the result and give it to the browser.

I found an example on the ASP.NET site (under the heading LESS, CoffeeScript, SCSS, Sass Bundling.). This has given me a LessTransform class that looks like this:

public class LessTransform : IBundleTransform
{
    public void Process(BundleContext context, BundleResponse response)
    {
        response.Content = dotless.Core.Less.Parse(response.Content);
        response.ContentType = "text/css";
    }
}

and this line in my BundleConfig class:

bundles.Add(new Bundle(
    "~/Content/lessTest", 
    new LessTransform(), 
    new CssMinify()).Include("~/Content/less/test.less"));

finally I have the following line in my _Layout.cshtml, in the <head>:

@Styles.Render("~/Content/lessTest")

If I have the site in debug mode, this is rendered to the browser:

<link href="/Content/less/test.less" rel="stylesheet"/>

The rules in the .less file are applied, and following that link shows that the LESS has been correctly transformed into CSS.

However, if I put the site into release mode, this is rendered out:

<link href="/Content/less?v=lEs-HID6XUz3s2qkJ35Lvnwwq677wTaIiry6fuX8gz01" rel="stylesheet"/>

The rules in the .less file are not applied, because following the link gives a 404 error from IIS.

So it seems that something is going wrong with the bundling. How do I get this to work in release mode, or how do I find out what exactly is going wrong?

Answer

David Kirkland picture David Kirkland · Dec 20, 2013

As a complement to the accepted answer, I created a LessBundle class, which is the Less eqivalent of the StyleBundle class.

LessBundle.cs code is:

using System.Web.Optimization;

namespace MyProject
{
    public class LessBundle : Bundle
    {
        public LessBundle(string virtualPath) : base(virtualPath, new IBundleTransform[] {new LessTransform(), new CssMinify()})
        {

        }

        public LessBundle(string virtualPath, string cdnPath)
            : base(virtualPath, cdnPath, new IBundleTransform[] { new LessTransform(), new CssMinify() })
        {

        }
    }
}

Usage is similar to the StyleBundle class, specifying a LESS file instead of a CSS file.

Add the following to your BundleConfig.RegisterBundles(BundleCollection) method:

bundles.Add(new LessBundle("~/Content/less").Include(
                 "~/Content/MyStyles.less"));

Update

This method works fine with optimization switched off, but I ran into some minor problems (with CSS resource paths) when optimization was switched on. After an hour researching the issue I discovered that I have reinvented the wheel...

If you do want the LessBundle functionality I describe above, check out System.Web.Optimization.Less.

The NuGet package can be found here.