Home » Code » Setting up Sass with Grunt

Setting up Sass with Grunt

Posted by on November 18th, 2013

Setting up Sass with Grunt
In last week’s tutorial, we started looking at Grunt as a tool to automate a lot of the repetitive jobs of building a web application. Stuff like compiling Sass, linting Javascript, minification and concatenation are all jobs that we can automate using a tool like Grunt.

Last week’s tutorial was an overview of the benefits of Grunt as well as a quick setup to show you how easy it is to get started. In this week’s tutorial I want to start to scratch the surface of a full Grunt setup to really show you the power of Grunt. This week I will be looking at setting up Sass, and configuring Grunt to do some nice little jobs for us.

So if you are knew to Grunt and you haven’t already read last week’s introductory tutorial, go read that now!

Installing Grunt

Just as a quick refresher from last time, I’ll go over setting up Grunt in a project.

First we need to set up the Grunt CLI

npm install -g grunt-cli

Next we need to install Grunt

npm install -g grunt-init

Finally, to generate the package.json file, simply run:

npm init

This should prompt you with some questions about your project. Don’t worry about your answers, you can easily change any of them once the package.json file has been generated.

Once the generator had finished I modified my package.json file slightly. This is what my file ended up looking like:

{
  "name": "Cribbb",
  "title": "I need to think of a catchy title",
  "url": "http://cribbb.com",
  "author": "Philip Brown",
  "copyright": "2013",
  "version": "0.0.1",
  "license": "GNU",
  "repository": {
    "type": "git",
    "url": "git://github.com/cribbb/cribbb.git"
  }
}

Finally we can actually install Grunt into this project. Run the following command in Terminal:

npm install grunt --save-dev

This should add the following section into your package.json file:

"devDependencies": {
  "grunt": "~0.4.1"
}

For a full explanation into how installing dependancies works, have a read of last week’s tutorial.

Creating the GruntFile

Now that we have the package.json set up we need to create it’s partner in crime, the GruntFile.js file. This is just a regular Javascript file that we can create as you normally would.

/*!
 * Cribbb Gruntfile
 * http://cribbb.com
 * @author Philip Brown
 */

'use strict';

/**
 * Grunt Module
 */
module.exports = function(grunt) {

};

Grunt configuration

The first thing to do is to create the Grunt configuration:

/**
 * Configuration
 */
grunt.initConfig({

});

The Grunt configuration is used to set up how we want the various dependancies of the project to work. Each dependancy will usually have a range of options that you can configure.

The first thing to do is to load the package.json file that we created earlier.

/**
 * Get package meta data
 */
pkg: grunt.file.readJSON('package.json'),

Remember, the GruntFile.js is just a regular Javascript file so loading the package.json file allows us to access the meta data through the pkg variable.

We can also set some additional variables to make working with file paths easier and to prevent repetition:

/**
 * Set project object
 */
project: {
  app: 'app',
  assets: '<%= project.app %>/assets',
  src: '<%= project.assets %>/src',
  css: [
    '<%= project.src %>/scss/style.scss'
  ],
  js: [
    '<%= project.src %>/js/*.js'
  ]
},

Setting a project banner

Have you ever seen the comment banners at the top of Open Source files? Generating these banners and automatically prepending them to our files is a really nice thing that Grunt can take care for us and it shows how powerful using our package meta data can be.

Add the following to your GruntFile

/**
 * Project banner
 */
tag: {
  banner: '/*!\n' +
          ' * <%= pkg.name %>\n' +
          ' * <%= pkg.title %>\n' +
          ' * <%= pkg.url %>\n' +
          ' * @author <%= pkg.author %>\n' +
          ' * @version <%= pkg.version %>\n' +
          ' * Copyright <%= pkg.copyright %>. <%= pkg.license %> licensed.\n' +
          ' */\n'
},

Now whenever we need to generate a banner at the top of a file, we can effortlessly get Grunt to do it for us.

Setting up Sass

As I mentioned in a previous tutorial, Sass is my preprocessor of choice and fortunately Grunt has an excellent plugin for handling it.

To install Sass, simply run the following command in Terminal:

npm install grunt-contrib-sass --save-dev

Next add the following to your configuration options:

/**
 * Sass
 */
sass: {
  dev: {
    options: {
      style: 'expanded',
      banner: '<%= tag.banner %>',
      compass: true
    },
    files: {
      '<%= project.assets %>/css/style.css': '<%= project.css %>'
    }
  },
  dist: {
    options: {
      style: 'compressed',
      compass: true
    },
    files: {
      '<%= project.assets %>/css/style.css': '<%= project.css %>'
    }
  }
},

The Sass configuration is basically broken down into two sections, dev and dist for development and production. This allows us to set different options for the different outputs depending on the environment. For example, you will want your production stylesheets to be compressed, but whilst in development we would want the output which is generated to be expanded. You will also notice that I have specified that Compass should be loaded, and for the development branch I will also prepend the banner that we defined earlier.

Finally you must specify where the input and output files are located. The output is the first option and the input is the second.

For a full list of configuration options, take a look at the documentation.

Watching for changes

Running the grunt command every time you want to compile your Sass into CSS is going to get pretty tedious really quickly and kind of defeats the objective of automating things.

Instead of running things manually, we can set Grunt to “watch” our files for changes. This means whenever a file that we are watching is changed, we can automatically run a set of tasks.

To install the Watch dependency, run the following in Terminal:

npm install grunt-contrib-watch --save-dev

Next, add the following to your configuration:

/**
 * Watch
 */
watch: {
  sass: {
    files: '<%= project.src %>/scss/{,*/}*.{scss,sass}',
    tasks: ['sass:dev']
  }
}

Here we are basically saying, whenever a file that matches this pattern is changed, run this command. So whenever a file under the scss directory is updated, run the sass:dev task.

To keep things relatively simply I’ll only install Sass for this tutorial. In future tutorials I will cover adding additional plugins as I need them.

Loading Grunt plugins

Now that we have our configuration set up, we need to load the plugins. You might remember from last week where we had this line of code:

grunt.loadNpmTasks('grunt-contrib-uglify');

In order for the Grunt tasks to be run, we need to first load the plugins. Using the syntax above we would have to list out every plugin that we require. However instead of manually loading this plugins, we can load them dynamically using the matchdep package.

To install the matchdep package, run the following in Terminal:

npm install matchdep --save-dev

Next add the following line to your GruntFile:

/**
 * Load Grunt plugins
 */
require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);

This will now automatically load all of your Grunt plugins so you don’t have to manually list them out and keep that list up-to-date.

Grunt tasks

Finally we need to set up the task to run Grunt:

/**
 * Default task
 * Run `grunt` on the command line
 */
grunt.registerTask('default', [
  'sass:dev',
  'watch'
]);

The default grunt task will run the dev branch of Sass and Watch. If you now save your GruntFile.js and run the grunt command in Terminal, you should see Sass compile and Grunt start watching your Sass files.

Now if you make a change to your Sass file, you will see the Sass task automatically run to recompile your Sass into CSS.

Conclusion

Grunt is an amazing tool for automating a lot of the repetitive tasks of Web Development. Things like compiling Sass or unit testing Javascript should automatically occur whenever a file is saved. Fortunately, Grunt can handle all of these little tasks for us.

Over the last two tutorials I’ve covered setting up Grunt in a project and adding Sass. However there is much more that you can accomplish with Grunt. When a project has a fast growing ecosystem like the one that Grunt has, you can guarantee that a lot of the problems you face will have already been solved.

Grunt is very much a staple of of my projects and has quickly found itself to be an extremely important tool in my box of tricks. In future posts I will be covering when I add new plugins to the project and how I configure things, but I probably won’t be dedicating any more full posts to Grunt specifically.

If you are looking for more information on setting up Grunt, I would highly recommend taking a look at FireShell. I’ve picked up a lot of really good practices from reading through the code, so I’m sure you will be able to learn a lot from it too!

This is a series of posts on building an entire Open Source application called Cribbb. All of the tutorials will be free to web, and all of the code is available on GitHub.

To view a full listing of the tutorials in this series, click here.

Philip Brown

Hey, I'm Philip Brown, a designer and developer from Durham, England. I create websites and web based applications from the ground up. In 2011 I founded a company called Yellow Flag. If you want to find out more about me, you can follow me on Twitter or Google Plus.

Join the Culttt

Become an insider and join the Culttt

  • Pingback: Getting started with Grunt | Culttt()

  • sergigp

    Hi Philip,

    First of all thanks for all your posts. It’s been very useful for me ;)

    I am a backend developer (i’m trying to do things with javascript in the frontend too with backbone and marionette) and I’m just starting with Sass (with bourbon).

    I have been watching some posts about Grunt but I don’t really know how many thinks we can do with Grunt. I can set a watcher with sass simply with sass –watch. I see Grunt has a couple of file with config … what are the advantages of Grunt?. I’m used to minify js when i deploy my applications with an IDE or Codekit and for the moment i don’t use coffeescript.

    What do you think Grunt can offer to people like me?

    PD: sorry about my english :/

    • http://culttt.com/ Philip Brown

      Thank you :) glad you are finding them useful.

      For me, I love how Grunt allows me to tie all of those processes into one version controlled source. When you are working as part of a team of developers, you will want everyone’s set up to be exactly the same. Using Grunt you can standardise how Sass is compiled, JS minified and how the build process works for shipping code to production. You wouldn’t want variations to creep in because everyone has a different set up.

      Grunt also makes it really easy to distribute your software. If you look at a project like https://github.com/TryGhost/Ghost. The Ghost team are able to standardise their build process so anyone installing the software doesn’t have to set up the Sass gem or use Codekit etc.

      I think if you are working on your own and you already have your environment set up so you can get the output you are looking for, Grunt is perhaps just another thing to learn. But I think Grunt is the future of how we (as developers) will handle all of these auxiliary tasks that are required for building really great online software.

      • sergigp

        Thanks for you answer Philip !!!

        I will take a look to Grunt as soon as I can ;)

  • Ryan

    If I wanted to use a Bootswatch Bootstrap 3 theme for quick development and then over-ride some styles should I bother with Grunt or SASS?

    You can get the bootswatch themes in LESS format, so maybe I should stick with LESS for this project?

    • http://culttt.com/ Philip Brown

      Hmm, I’m not familiar with that set up. I guess it probably depends on what you are trying to achieve. An easy approach might be to use those stylesheets as a base and then use Grunt to concatenate and compress the base and your style layer together.

  • Pingback: Multi-Tenancy in Laravel 4 | Culttt()

  • Nirmal Thapa

    Just a quick info to all the readers like me:
    (I am following Philip’s posts and its been quite a while, but in this particular post I really needed to jump out of it to other places to really know about all the bits mentioned here in this post. Because to make it work and pass this post, there are many things that should work in tandem)

    1. Make yourself familiar with gruntFile.js (I really mean it !). The link down below makes everything so much clearer.

    http://gruntjs.com/sample-gruntfile

    2. For Sass along with compass to work as you expected:

    – make sure Ruby is installed
    – make sure SASS is installed
    – make sure COMPASS is installed too.

    3. Understand thoroughly all extra variables used in gruntFile.js (like project.app, project.assets……) and how they have been built up and implemented.

    • http://culttt.com/ Philip Brown

      Thanks Nirmal :) Glad you are finding my posts useful!

Supported by