I blog in a personal capacity about anything and everything going on in my life on freakcity but I thought I'd set up somewhere so I can post about techy type stuff that's relevant to me in my work.
So for my first post, here's a little bit of awesome, courtesy of Grunt.

So you want a livereload enabled development environment that minifies and concatenates your javascript and css?

  • Create an empty folder for your new website. Create a github repo and check it out in an empty folder if you so choose.
  • In this folder, create the following directory structure:

> src
  > js
     > libs
  > sass
  > images
  > fonts
  • Create a file called Gruntfile.js

  • Open this in a text editor and copy and paste the below:

    /jshint forin:true, noarg:true, noempty:true, eqeqeq:true, bitwise:true, strict:true, undef:true, unused:true, curly:true, browser:true, indent:4, maxerr:50 /
    /global require:false, module:false/
    var LIVERELOAD_PORT = 35729;
    var lrSnippet = require('connect-livereload')({port: LIVERELOAD_PORT});
    var mountFolder = function (connect, dir) {
    'use strict';
    return connect.static(require('path').resolve(dir));
    };
    module.exports = function(grunt) {
    'use strict';
    require('matchdep').filterDev('grunt-
    ').forEach(grunt.loadNpmTasks);
    grunt.initConfig({
    watch: {
    self: {
    files: ['Gruntfile.js'],
    tasks: ['jshint','build'],
    options: {livereload: true}
    },
    css: {
    files: ['site/css/**/
    .css'],
    options: {livereload: true}
    },
    sass: {
    files: ['src/sass/'],
    tasks: ['compass']
    },
    html: {
    files: ['src/
    /.html'],
    tasks: ['copy:html'],
    options: {livereload: true}
    },
    js: {
    files: ['src/js/**/
    '],
    tasks: ['jshint', 'uglify'],
    options: { livereload: true }
    },
    static: {
    files: ['src/images/', 'src/fonts/'],
    tasks: ['copy:static', 'compass'],
    options: {livereload: true}
    }
    },
    jshint: {
    all: [
    'Gruntfile.js',
    'src/js/.js'
    ]
    },
    uglify: {
    options: {
    beautify: false, /
    Swap these two to get uncompressed pretty output /
    mangle: true
    /
    ,
    preserveComments: 'some'/
    },
    app: {
    files: {
    'site/js/app.min.js' : ['src/js/app.js']
    }
    }
    },
    clean: {
    all: ['site/**/
    ']
    },
    connect: {
    options: {
    port: 9000,
    // change this to '0.0.0.0' to access the server from outside
    hostname: '0.0.0.0'
    },
    livereload: {
    options: {
    middleware: function (connect) {
    return [
    lrSnippet,
    mountFolder(connect, '.tmp'),
    mountFolder(connect, 'site')
    ];
    }
    }
    }
    },
    copy: {
    static: {
    files: [
    {
    expand:true,
    cwd:'src/',
    src:['favicon.ico','images/', 'fonts/', 'js/lib/'],
    dest:'site/'
    }
    ]
    },
    html: {
    files: [
    {
    expand: true,
    cwd:'src/',
    src:['
    /*.html'],
    dest: 'site/'
    }
    ]
    }
    },
    compass: {
    all: {
    options: {
    httpPath: '/',
    cssDir: "site/css",
    sassDir: "src/sass",
    imagesDir: "src/images",
    javascriptsDir: "site/js",
    fontsDir: "../fonts/",
    httpFontsPath: "../fonts",
    outputStyle: "compressed",
    lineComments: false,
    colorOutput: false
    }
    }
    }
    });
    grunt.registerTask('build', ['jshint', 'clean', 'copy', 'compass', 'uglify']);
    grunt.registerTask('server', ['build','connect:livereload','watch']);
    };

  • Save this file.

  • Create a file in the same location called package.json

  • Open this in a text editor and copy and paste the below:


{
    "name": "MyAppNameInCamelCaseWithNoSpaces",
    "version": "0.0.1",
    "homepage": "https://pages.github.com/...",
    "repository": {
        "type": "git",
        "url": "https://github.com/..."
    },
    "author": {
        "name": "My Name",
        "url": "http://my.url.com"
    },
    "devDependencies": {
        "connect-livereload": "~0.3.2",
        "grunt": "~0.4.1",
        "grunt-contrib-clean": "~0.4.0",
        "grunt-contrib-compass": "~0.2.0",
        "grunt-contrib-connect": "~0.2.0",
        "grunt-contrib-copy": "~0.5.0",
        "grunt-contrib-jshint": "~0.8.0",
        "grunt-contrib-uglify": "~0.2.7",
        "grunt-contrib-watch": "~0.5.3",
        "matchdep": "~0.1.1"
    }
}
  • Change stuff in this file at the top (name, homepage etc)
  • Save this file.
  • optionally create a .gitignore file if you're using git with the contents:
node_modules/
*.log
.DS_Store
Thumbs.db
.sass-cache
site/

Once you've finished, you should make sure you have node and NPM installed. On OSX, I'd strongly recommend installing Homebrew and then running brew install node. On Windows, you can grab it from here: http://nodejs.org
Once installed and you have verified your install by running node -v from the command line and getting the expected output ( v0.10.24 as of writing), you're ready to install the dependencies.

Run npm install -g grunt-cli

In the root directory (the one with the Gruntfile.js in it) run npm install and let node install everything it requires.

  • Create an index.html file in the root of src.
  • Create a JS file called app.js in src/js. You can put any JS libs you need inside of src/js/libs.
  • Create a sass file called main.scss in src/sass.
  • main.sass will compile into /site/css/main.css
  • app.js will compile into /site/js/app.min.js
  • Add links inside your HTML to js/app.min.js and css/main.css
  • Now you're all set. Run grunt server inside of your terminal and it should run and start a server that you can access at http://localhost:9000

Voila! A Livereload enabled development environment. You'll notice whenever you save anything the browser auto refreshes.