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.

How to Remove Sass Cache From a Git Repo

On most projects, there are going to be some files you don’t need or want in its git repo, but you might not always think about them until they’re already in there. When the project involves Sass, the Sass cache directory is one of those things that aren’t really needed or wanted in the repo. No sweat, this is a fixable issue.

First things first, back up the directory:

cp .sass-cache .sass-cache2

Next, enter the following command:

git filter-branch -f --tree-filter 'rm -rf path/to/your/.sass-cache' HEAD

Now if you try to push to your remote like normal, you will probably get an error with something like this:

! [rejected]        master -> master (non-fast-forward)

This is because, as the error will explain, your remote repo now has files that your local repo is missing. You want to remove the .sass-cache from the remote, too, so force the push like this:

git push origin master --force

Make sure to change the branch name from “master” to the branch where you want to code pushed, of course. The important part here is just the “–force” flag.

When the push is sucessful, go ahead and take a look at the files in the remote branch where you pushed the code. The .sass-cache directory won’t be there. Nice! You’re a little closer to having a cleaner Git repo.

But you don’t want to do this again, right? If you don’t already have a .gitignore file, put one in the root directory of your local repo:

touch .gitignore
nano .gitignore

Replace “nano” with your preferred terminal text editor. Now add the following and save the file:

path/to/your/.sass-cache

Go ahead and check the status of your local repo:

git status

You won’t see Git telling you there’s .sass-cache files to add to staging. It ignored them, as we desired.

Yeoman: Getting it to Work on Ubuntu

In case you haven’t yet heard the buzz, Yeoman is one of the best front end development inventions since sliced bread. Think of it as having a jolly little British man living inside your command tool, awaiting your requests. Need to scaffold out an Angular project fast? He’s on it. Need to minify your style sheets and scripts? Already done. Want to download a good pint? Well, perhaps one day when the technology for teleportation is there…

 

Yeoman

Why Put Yeoman to the Job?

In recent months, I’ve been asked by my workplace to get cozy working with AngularJS, which is a great JavaScript framework if you haven’t already checked it out. When I cracked open my new book, though, it became apparent that a tool like Yeoman would be an immense, time-saving help. Why is that? There are numerous tools that can help make an Angular app rock solid, such as Jasmine and Karma Runner (both are JavaScript testing tools). Now you could spend time at the beginning of each project downloading all of the various files needed for each framework or plugin and assemble them by hand, but not only is that needlessly time-consuming, it’s also prone to human error.

It Doesn’t “Just Work”

At the office, I use a Mac, and it’s great. Installing Yeoman on that computer was a breeze (not counting the initial installation of tools needed just to use a Mac terminal for development in general… I use Homebrew).

The problem with installing Yeoman on Ubuntu is it’s not a Mac, but most online instructions are written for Mac users. Also, I use Oh My Zsh for my terminal, which depends on zsh, not bash. I went through a maddening labyrinth of permissions and zsh profile editing, along with many screw ups, before coming up with just the right set of steps to get Yeoman running on my Ubuntu 13.10 computer.

Headache #1 – Installing Node

Yeoman runs on Node to make use of its package manager tool, NPM. If you’ve worked with Ruby in the command line at all, using NPM to install packages is similar to installing gems. Like using Ruby to run Sass, you don’t need to know too much about Node to make use of Yeoman, but you do need to have it working.

Open up your terminal and enter the following commands to install your Node dependencies:

sudo apt-get update
sudo apt-get upgrade
sudo apt-get install build-essential openssl libssl-dev curl

Now that your dependencies are in order, install Node:

sudo apt-get install nodejs
sudo ln -s /usr/bin/nodejs /usr/bin/node
curl https://npmjs.org/install.sh | sudo sh

See that second line? On Ubuntu, there’s already a tool called “Node” that would otherwise cause a name conflict, so when Node installed on your system, it called itself something a little different, “NodeJS.” That’s all fine and good, but it can cause some issues later. The symlink created will make it as if your installation of Node were actually in the node directory. The third line installs NPM into your shell (the terminal).

Headache #2 – Installing Anything with NPM

At this point, if you try to install anything using NPM, you might see some big, nasty permissions errors… or nothing at all. When I first attempted to install Yeoman on my Ubuntu laptop, I got Yeoman installed, but issuing it commands got me nothing but the sound of crickets chirping.

Here’s the commands you can run in your terminal to prevent those errors:

echo prefix = ~/.node >> ~/.npmrc
echo 'export PATH=$HOME/.node/bin:$PATH' >> ~/.bashrc
. ~/.bashrc

Now if you’re a member of the zsh master race, change both instances of “~/.bashrc” to “~/.zshrc” so that you’re writing to the correct profile file.

Now Install Yo

Sorry, I kinda, sorta lied. Yeoman got a name change not to long ago, and it’s now going by just “Yo.” Now here’s the way to install Yo:

npm install -g yo

Easy peasy, lemon squeezy, right? Right.

Now that you have Yo installed, it’s time for a test flight. In your terminal, navigate into a directory where you’d like to start a new project. Now, just say:

yo

If everything went well, you should have a menu of options, including “Install a generator.” Select that one, and then at the prompt, type in something like “Angular” or “Ember,” or whatever sounds good to you (sorry, I tried “beer,” but there wasn’t any available yet). Choose one of the generators that pops up and wait for it to install.

Generators are Yo’s scaffolding tools. Think of them as blueprints for the foundations to your projects. Once he’s got one of these, your Yeoman has all the instructions necessary to lay down some ground work.

Now go ahead and select “Run the [name of your new generator here]” by selecting it at the prompt. If the generator starts pulling down some files and doesn’t issue you any errors, then you know that Yo is working just fine. Jolly good!

Getting More Help

The following links helped me figure out Yeoman installation, so maybe they’ll help you, too…