LESS with .NET bundling and minification (+Bootstrap)

There are two things you always have to do when building a website or web application: use a CSS preprocessor and bundle and minify your style/script resources. Using a preprocessor makes writing CSS not so horrible and bundling and minification gives you great performance advantages when you minimize your request amount and size.
Bundling and minification is usually done with grunt or gulp.js but in .NET environment you can take advantage of Microsoft ASP.NET Web Optimization Framework.

This guide will tell you how to use LESS as the CSS preprocessor along with bootstrap‘s LESS source and .NET bundling and minification.

1. Install a few NuGets

You need a couple of NuGets to get LESS with bundling and minification up and running. One of them is BundleTransformer.LESS that requires a javascript engine switcher. At the time there are two options for JS engine switchers: V8 and Msie. V8 didn’t work for me (with bootstrap), hence Msie.

Install these (and some dependencies along with them):

  • BundleTransformer.Less
PM> Install-Package BundleTransformer.Less  
  • JavaScriptEngineSwitcher.Msie
PM> Install-Package JavaScriptEngineSwitcher.Msie  
  • Twitter.Bootstrap.Less
PM> Install-Package Twitter.Bootstrap.Less  

2. Modify your Web.config

Add the JS engine switcher config inside <bundleTransformer> block in your web.config: <less><jsEngine name="MsieJsEngine" /></less>.

<bundleTransformer xmlns="http://tempuri.org/BundleTransformer.Configuration.xsd">  
    <core>
      ...
    </core>
    <less useNativeMinification="false" ieCompat="true" strictMath="false" strictUnits="false" dumpLineNumbers="None" javascriptEnabled="true">
      <jsEngine name="MsieJsEngine" />
    </less>
  </bundleTransformer>
  <jsEngineSwitcher xmlns="http://tempuri.org/JavaScriptEngineSwitcher.Configuration.xsd">
    <core>
      <engines>
        <add name="MsieJsEngine" type="JavaScriptEngineSwitcher.Msie.MsieJsEngine, JavaScriptEngineSwitcher.Msie" />
      </engines>
    </core>
  </jsEngineSwitcher>

Try switching the compilation debug attribute to false to see bundling and minification in action while debugging:

<system.web>  
    <compilation debug="false" targetFramework="4.5" />
</system.web>  

3. Add a LESS bundle to BundleConfig.cs

Now you’re all set to create your LESS bundles:

using BundleTransformer.Core.Transformers;  
namespace LessSample {  
  public class BundleConfig {
    public static void RegisterBundles(BundleCollection bundles) {

      var lessBundle = new Bundle("~/css").Include(
        "~/Content/bootstrap-customer.less",
        "~/Content/main.less"
        );

      lessBundle.Transforms.Add(new StyleTransformer());
      lessBundle.Transforms.Add(new CssMinify());
      bundles.Add(lessBundle);
    }
  }
}

Bootstrap LESS source .NET

One thing to notice there in the bundle is bootstrap-customer.less. This is a customer specific bootstrap .less file that simply contains something like this:

@import 'bootstrap/bootstrap.less';
@import 'variables-customer.less';
@import 'theme-customer.less';

I import the original bootstrap that’s installed via NuGet and after that I import the customer specific variables and theme which overrides the default bootstrap styles. You don’t want to do the importing in main.less directly because this way you can debug your site with bootstrap separated from your custom styles.