Let's get started!
First off, I might recommend that you install SassyStudio for Visual Studio to help you with writing SASS in your favourite IDE. This is not required, but it's makes your SASS code nice and colourful. :)
However, Ruby is a requirement, and here is the easiest way to you install it. Head over to http://rubyinstaller.org/ and click the massive "Download" button and select the latest stable build that is suitable for your development environment (in my case it was Ruby 2.0.0-p481). Once downloaded, run the installer and follow the steps as per standard procedure. Only remember to check "Add Ruby executables to your PATH". If you forget to check it, don't worry, you just need to add the Ruby installation directory to your environment variables.
Once the installation is complete, open what should now be your best buddy; i.e. the command prompt; and run:
ruby -h
If ruby is installed correctly, you should get a list of ruby commands, otherwsie "Bad command or file name". If your command prompt was open, you may need to close it and re-open to be able to use the newly added environment variables.
Now let's install our compass gem and it couldn't be simpler. Still in the command prompt, simply run:
gem install compass
And if you wish to install any of compass' predefined templates, such as the highly-recommended HTML5 Boilerplate:
gem install compass-h5bp
Before we jump back into our Grunt file, we need to install compass for our project; which sets up a file appropriately entitled config.rb and also creates the necessary asset directories, such as the css, sass and image folders.
Let's add SASS and Compass to last time's grunt file. If you remember well, the first step would be to install the pacakge through npm.
npm install grunt-contrib-compass --save-dev
compass: { dev: { options: { outputStyle: 'expanded' } }, dist: { options: { outputStyle: 'compressed' } } }
As you can see, we have set up two configurations for compass, one for 'dev' and one for 'dist' (aka distribution or production). This allows us to have different setups when building to the dev or live environment, such as not minifying JavaScript or CSS for the development environment, but doing so for the production environment. We need to then register two different tasks, with the default being the one run when calling 'grunt' whilst the 'dist' is called when passing the respective 'dist' argument:
grunt.registerTask('default', ['concat', 'compass:dev', 'watch']);
grunt.registerTask('dist', ['concat', 'uglify', 'compass:dist', 'watch']);
The ultimate step to have a beautifully working project using SASS & Compass is to include the compass task in the watch task.
mySass: { files: '**/*.scss', tasks: ['compass'], options: { spawn: false, }, }
Let's take a breath and recap what we should have done so far. In last time's blog, we introduced Grunt, and included three tasks, to concatenate and minify JavaScript and another task to place a watch on that folder and re-run the specified tasks whenever a change is detected. Today we installed Ruby and Compass (a ruby gem) and added Compass to our gruntfile. Similarly to the concatenation and minification tasks, we also included Compass in our watch task to re-compile the SASS files whenever they are changed.
If you will be using the HTML5 Boilerplate template (or any other one); don't forget to include a reference towards it in your config.rb file. This should be the first line and follow the following format:
require 'compass-h5bp'
You're now probably looking at your gruntfile and wondering what this ugly beast is supposed to be. You must have approximately 200 lines of unstructured JSON and you might already be stressing over the maintenance that such a big file is going to cause to you and your team. There is a great article by Paul Bakaus about restructuring your gruntfile and most of the ideas below are taken from this same piece; bottom-line, we will split up our gruntfile into multiple smaller files.
Let's get started and install the npm package:
load-grunt-config
We then rewrite our gruntfile to only contain the following:
module.exports = function (grunt) { require('load-grunt-config')(grunt); };
This task searches in the root folder of your project for a folder entitled 'grunt' and searches for the aliases.js file. This sole responsibility of this task would be to register your grunt tasks, such as the previous 'default' and 'dist'.
module.exports = function (grunt) { grunt.registerTask('default', ['concat', 'compass:dev', 'watch']); grunt.registerTask('dist', ['concat', 'uglify', 'compass:dist', 'watch']); };
Grunt will then search for files that match the task names, i.e. concat.js, uglify.js, compass.js and watch.js and execute these tasks according to their options detailed within their respective file, so taking the 'concat' as an example, it would only contain the options relevant to that task:
module.exports = { dist: { src: ['scripts/*.js'], dest: 'scripts/build/script.js', } };
This way we follow the single-responsibility principle and each file has only one role, making for a more maintainable solution.
I think I have already said too much and there is a bit of code to work with, but I also included a demo app if you're stuck and need to do some copy paste.
Thanks for reading and have a fantastic weekend.