Tuesday 16 December 2014

Refactoring My Website - Part 1

It has been a while since I built my personal website, theo-nicolaou.co.uk. My main aim at the time was to keep it simple - updates had to be quick and easy, and I felt the design could be relatively simple too. I just wanted to be able to showcase my work and use the site as a mini-playground for experimenting and learning things like HTML5 and responsive design.

A few years down the line and the requirements haven't really changed. I'm happy with the design overall (although I might tweak it slightly in due course) and it is still pretty easy to update considering it is built by hand - adding a new item of work to the site, including preparing the images in Photoshop, takes no more than 30 minutes. However, the code behind the scenes is a little outdated so I thought I would take the opportunity to spruce it up a little and continue with the experimentation and learning. I have also been planning to create a basic Grunt file to eventually use in future projects - I thought I could get started on this by writing it in the context of my website.

This blog post is one in a series detailing how I went about my website refactor.

For reference, my website currently links to two CSS files - tn.css and tn-mediaqueries.css and a few JS files such as respond.js and HTML5 Shiv. My main focus to begin with will be the CSS files. As you can see, there are quite a few changes which I could make. Overall they wouldn't take a huge amount of effort but they would help improve the scalability and maintenance of the code:
  • Turn CSS into SCSS
  • Split CSS into SCSS partials
  • Consolidate duplicate CSS properties
  • Change element selectors into classes
  • Nest selectors
  • Use variables
  • Use mixins for projectlistitem selectors? e.g. projectlistitem-UKC
  • Remove /*/mediaquery*/ hack from mediaqueries file (not sure what this is, perhaps it was to support IE7?)
  • Adjust breakpoints (905px and 1105px??)
  • Try to write code mobile-first i.e. no need for small-screen media queries
  • Move media queries into classes or within partials
I could probably review the names of the classes themselves, but I'll see how it goes after I finish everything else.
The Grunt file could include the following plugins:
  • SCSS compilation
  • Watch
  • LiveReload
  • Image Optimisation 
  • OS X Notifications
And then if I wanted to extend it further, perhaps I could add these:
  • Concat
  • Minify
  • Lint
First, I wanted to set everything up and make sure everything was working. I had to install Node.js on my Mac (and NPM, but Node.js includes this anyway), and then install Grunt. After that, my first milestone would be to convert my CSS into SCSS files, and then set up the Grunt file to compile back into CSS.

So, let's get started!
  1. To install Node, go to http://nodejs.org and click "Install".
  2. Then, run the following command to make sure you have the latest version of NPM:

    sudo npm install npm -g
After I installed Node and NPM, I moved on to setting up Grunt and the package.json file that goes with it. More details can be found all over the internet, mainly on the Grunt website but also I do like this tutorial alot.
I set up my package.json file by running the following command in Terminal:
npm init
This presents a series of basic questions to help set up your package.json file.

Then, I ran the following command to install the Grunt Command Line Interface (Grunt CLI). This will allow you to use Grunt wherever you like your machine:
sudo npm install -g grunt-cli

Finally, I created an empty Gruntfile.js in the root of my project. With the very basic foundations in place, I moved on to installing the Grunt plugins which would enable me to compile SCSS into CSS. All the plugins are installed using the command "npm install <plugin>". Top of the list was Grunt itself. I know, a bit odd that you need to install a Grunt plugin to use Grunt, when you have already installed the Grunt CLI. But, whatever...
npm install grunt --save-dev

When the first Grunt plugin is installed, a "node_modules" folder is created in the project root. Inside this folder are the relevant files for the Grunt plugins themselves.

Next I installed the Grunt Sass plugin (to compile SCSS into CSS). In addition to this, I installed the Watch plugin (to trigger compilation when any specified file types are modified), an image optimisation plugin to compress all my images, and the OS X Notifications plugin (because it is cool). I wanted to use the LiveReload plugin (because manually refreshing your browser is *so* last year) but I found out that it has been deprecated and the functionality moved into the Grunt Watch plugin.
npm install grunt-contrib-sass --save-dev
npm install grunt-contrib-watch --save-dev
npm install grunt-image --save-dev
npm install grunt-notify --save-dev
Wow. I know what you're thinking: all this and still not anywhere near the CSS yet! Never fear, we're not far off the first milestone. I copied my two CSS files, saved them in a folder called "SCSS" and renamed them to "tn.scss" and "tn-mediaqueries.scss". Then, in my Gruntfile.js I added the configuration so that it would look at the specific SCSS files and compile them into the CSS files (with names that I specify). The Grunt file can be found here.

You'll notice that the file does not include any configuration for the other plugins - I will configure these and explain how I did this in a future post. For now, that's it - the ball is rolling on my website refactor project. I hope you enjoyed reading this post and I hope you will come back to read the next in this series, where I will continue with the code cleanup and the Grunt config.