Better Workflow for LESS Stylesheets in ASP.NET vNext

If you’ve been following along, my last post was about working with LESS stylesheets. I started working with LESS stylesheets in Visual Studio 2013. There the workflow was great. I just saved the less file and Visual Studio automatically created the css file for me. All I had to do was reload my browser and I could check out my changes. This is a part of Web Essentials – something that is unlikely to work cross-platform. Let’s use Grunt instead!

The grunt plugin we want is called grunt-contrib-watch. it’s entire function is to monitor files for changes. If one of the files changes it will run another grunt task. This sounded just like what I wanted. There was a great blog post by JonathanMH that got me mostly there, so thanks for that.

The actual grunt task is almost anti-climatic. We’ve done a whole bunch of things in grunt by now, so this should be old hat. Insert this code snippet into the grunt.initConfig() method:

    watch: {
      files: "wwwroot/site/*.less",
      tasks: ["less:development"]
    }

You will also need to add the ‘grunt-contrib-watch’ module – once in the Gruntfile.js:

  grunt.loadNpmTasks("grunt-contrib-watch");

… and once in the package.json file to get the node package manager to load it.

The other part is to get it running. I placed the watch task in my project-open alias task, like this:

  grunt.registerTask("project-open", [ "watch" ]);

If you’ve already been following along, this is then bound to the Project Open binding in the Task Runner Explorer. Use File->Close Solution, then re-open your solution. The Task Runner Explorer will show that project-open is running and it will stay running. Don’t kill it. If you do kill it, don’t worry – you can just go into the Tasks, right-click on the watch task and Run it again.

Start your website. Make a change to one of your less files. Note that the site.css file was re-built. You can now refresh your browser and your changes are included in the build.

This means, ultimately, that you don’t need to re-start your web server after each and every change you make that requires a client file rebuild.

For those that want it, here is my complete Gruntfile.js file:

/// <binding BeforeBuild='before-build' AfterBuild='after-build' Clean='clean' ProjectOpened='project-open' />
/*
This file in the main entry point for defining grunt tasks and using grunt plugins.
Click here to learn more. http://go.microsoft.com/fwlink/?LinkID=513275&clcid=0x409
*/
module.exports = function (grunt) {
  grunt.initConfig({
    bower: {
      install: {
        options: {
          targetDir: "wwwroot/lib",
          layout: "byComponent",
          cleanTargetDir: true
        }
      }
    },
    less: {
      development: {
        files: {
          "wwwroot/site/site.css": "wwwroot/site/site.less"
        }
      }
    },
    watch: {
      files: "wwwroot/site/*.less",
      tasks: ["less:development"]
    }
  });

  grunt.registerTask("before-build", ["bower:install", "less:development"]);
  grunt.registerTask("after-build", []);
  grunt.registerTask("clean", []);
  grunt.registerTask("project-open", [ "watch" ]);

  // The following line loads the grunt plugins.
  // This line needs to be at the end of this file.
  grunt.loadNpmTasks("grunt-bower-task");
  grunt.loadNpmTasks("grunt-contrib-less");
  grunt.loadNpmTasks("grunt-contrib-watch");
};