Adding Grunt to an Existing Compass Project

Grunt is super cool. Compass is super cool. These tools both automate things for you, which is awesome. The only thing even awesomer? Putting the two together.

Who Should Read This Tutorial and How to Get Started

This tutorial is about how to add some Grunt goodness to a pre-existing Compass project. It’s assumed you’re in the know about Compass and at least have an idea about what Grunt does. If not, visit the Compass website or the GruntJS website, or both, to learn more.

Another pre-requisite is that you have Node and NPM (Node Package Manager) installed. Similar to Ruby, depending on your development environment this might be super easy or a bit tricky. Visit the NodeJS website for download and installation instructions. If you have trouble with that, and you’re using Ubuntu and possibly ZSH, try out my Yeoman: Getting it to Work on Ubuntu tutorial and read the section on Node there.

The Existing Compass Project

You have an existing Compass project. That alone does some cool things that some people also use Grunt to do, like minifying CSS and watching for changes to your Sass code. Still, Grunt is helpful even on a Compass project, because it can do things like concatenate and minify your JavaScript, optimize images, etc. We’re going to have Grunt take over the Sass compiling and CSS minifying tasks.

Getting Grunt & Compass Ready for the Dance

Get started by navigating to the directory for your Compass project. In the root directory of the project, create a file named “package.json” and add the following:

{
   "name": "project-name",
   "version": "0.1.0",
   "devDependencies": {
      "grunt": "~0.4.1"
   }
}

Change the name of the project to whatever you want, it doesn’t really matter. Leave the rest of that stuff alone.

In your terminal, run the following command:

npm install

This command installs Grunt into your project directory. If you weren’t previously using Grunt for anything and therefore haven’t gotten it installed yet, type this into the terminal next:

npm install -g grunt-cli

That command installs the command line tool for Grunt and makes it available for you to use in any project. Since I already had Yeoman installed, this wasn’t necessary for me. You can try moving forward without this and then run the command if you get a “command not found” error.

Now, you will need to make a Grunt file. In the root of the project directory, make a “Gruntfile.js” file and add this code:

module.exports = function(grunt) {
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),

        // configuration goes here

    });

    // some task setup will go here
};

This configuration file is just a skeleton at this point. We have to install some Node modules before putting anything cool in here.

Install Grunt-Contrib-Compass

Grunt uses Node modules to perform its various tasks. There is no definitive list of tasks Grunt can or cannot run… it’s all dependent on what modules are available. At minimum, you need grunt-contrib-compass installed if you want Grunt to take over Sass compiling duties.

npm install grunt-contrib-compass --save-dev

This command saves the module to your project. Now to use it, you need to set up some configuration in Gruntfile.js:

module.exports = function(grunt) {
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),

        compass: {
            dist: {
                options: {
                    config: 'config.rb'
                }
            }
        },

    });

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

    grunt.registerTask('default', ['compass']);
};

The “compass” block in Gruntfile.js is the configuration for the grunt-contrib-compass module. In a new Compass project, you can write the configuration of the Compass project itself into this block, but for an existing project, we’re just telling it to look at your config.rb file. The path is relative to the root of the project.

Loading the module takes place next, in the line that begins with “grunt.loadNpmTasks.” This is how you load any Grunt module into Gruntfile.js for use. Once that line is in there, and the above configuration block is correct, you can type “grunt modulename” into the terminal to run that task.

We want the “compass” task to run every time we type “grunt” into the terminal, so the next line registers a default task list with “compass” being the first entry. This is just an array, and you can add more tasks in there, which we’ll do later.

Save Gruntfile.js and test the configuration out by typing this command in the terminal (at your project root):

grunt

Grunt and Compass
When it works like it should, you will see that it compiled your Sass files. This is the equivalent of running:

compass compile

[note: Yeah, you should really not be watching the compass project in another terminal window or tab somewhere. If that stuff is still running, exit out of it.]

Install Grunt-Contrib-Watch

Now for the “watch” part. It’s fine to compile Sass using Grunt, but you wouldn’t want to give up the “watch” command that comes with Compass. Grunt can watch everything in your project, Sass files included, and perform the tasks you assign it. You will need to install grunt-contrib-watch for this.

Installation is the same as before:

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

There you go. Now for the Gruntfile.js additions:

module.exports = function(grunt) {
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),

        compass: {
            dist: {
                options: {
                    config: 'config.rb'
                }
            }
        },

        watch: {
            scripts: {
                files: ['sass/*.scss', 'js/*.js'],
                tasks: ['compass'],
                options: {
                    spawn: false
                },
            }
        }

    });

    grunt.loadNpmTasks('grunt-contrib-compass');
    grunt.loadNpmTasks('grunt-contrib-watch');

    grunt.registerTask('default', ['compass']);
};

There are a couple of things I’d like to point out about the above. First, I added both Sass and JavaScript files to “watch” so I could show how to watch other kinds of files. This tutorial doesn’t cover Grunt modules that handle JavaScript files, but it would be useful to learn that next. Another thing is that I did not add “watch” to “grunt.registerTask,” because I don’t want to run “watch” as part of my default list of tasks. That is just a personal preference, though. If you want “watch” in the default task, I would take out any tasks that are being handled by “watch.”

Now go back to the terminal:

grunt watch

Grunt Watch with Compass
[note: the screen shot shows "*.sass" files being watched, but my code examples are dealing with .scss files... this was a typo I made while taking the captures]

Great, now Grunt has taken over your Compass stuff. By itself, this is kind of useless, but your next step is to learn more about what kinds of tasks you can run using Grunt and add them to your project. Such tasks include concatenating files, optimizing images, linting CSS and JavaScript, etc.

Grunt Watch in Action

Bonus: Adding LiveReload to Grunt

iveReload is a browser extention that automatically refreshes your browser after you make changes to the stylesheet. I recommend using it with Chrome for the best results, so go get the Chrome LiveReload extension.

If you are using Linux, there’s an extra step here. Upon clicking on the LiveReload icon to turn on the extension in Chromium, it will tell you to install “guard-livereload” to use it.

Should you need guard-livereload, type this into your terminal:

gem install guard-livereload

Type “gem list” after that and make sure both “guard” and “guard-livereload” are installed. Now navigate to your home directory (cd ~ in the terminal works) and create a file named “Guardfile” (no extension) with the following code in it:

guard 'livereload' do
   watch(%r.+\.(css?)$})
end

Personally, I have not had this working with anything but Compass projects so far, but in theory you should be able to add JavaScript and HTML files, etc., to the list of files Guard should watch. That is more in the domain of Ruby projects, so if you’re a Ruby nerd reading this tutorial and know a better way to get this working, please drop me a line.

Now, users of both Mac and Linux platforms (sorry, Windows… maybe you can use CygWin?) should be ready to add LiveReload to the “watch” task in Grunt.

Go back into Gruntfile.js and edit the “watch” configuration block so it looks like this:

watch: {
   scripts: {
      files: ['sass/*.scss', 'js/*.js'],
         tasks: ['compass'],
            options: {
               spawn: false
            },
    }
}

Run “grunt” in the terminal again. Make sure that Grunt says it is watching your Sass files and no errors were generated. Start the LiveReload extension in Chrome by clicking on the icon, then make some changes to your Sass code. You should see the browser refresh with the new styles showing. If not, be sure to check if there is an error in the terminal.

Leave a Reply