Grunt.js

Repetitive Tasks Ain't Sh*t

Slides/Puppies/Bad Jokes by Andre Bluehs / @helloandre

Wait, Who Are You?

Georgia Tech, DeviantART, Beard

Wait, What Is Grunt?

Automated tasks written in javascript for javascript *

* among other things

Before Grunt?

Sad, Sad Times

  • Rake
    • Not Terrible
    • NOT A RUBY TALK
  • Make
    • - Horrendous DSL
    • + Incremental

Ok, Impress Me

Compile Anything/Everything, Lint Code, Watch For Changes, Run Tests, Build Zips, Mine Bitcoins, Launch Spaceships.

"I run on Javascript"

Stop Stalling

we want puppies

What This Talk Covers

  1. Starting
  2. Simple Tasking
  3. Multi Tasking
  4. Watching
  5. Slightly Difficult Tasking
  6. Other People's Things

Installing

npm install -g grunt-cli
npm install grunt --save-dev

package.json

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

Puppy One

Uglify Javascript

follow along at home: puppies/one/

package.json

{
    "name": "puppyone",
    "version": "0.1.0",
    "devDependencies": {
        "grunt": "~0.4.1",
        "grunt-contrib-uglify": "~0.2.4"
    }
}

Gruntfile.js

module.exports = function(grunt) {
    grunt.initConfig({
        uglify: {
            simple: {
                files: {
                    'build/app.min.js': ['src/jquery.js', 'src/app.js']
                }
            }
        } 
    });
    grunt.loadNpmTasks('grunt-contrib-uglify');
};

Command

grunt uglify

Puppy Two

<% pkg.first %> verse, same as <% pkg.first %>

follow along at home: puppies/two/

package.json

{
    "name": "puppytwo",
    "version": "0.1.0",
    "devDependencies": {
        "grunt": "~0.4.1",
        "grunt-contrib-uglify": "~0.2.4",
    },
    "srcpath": "src/",
    "destpath": "public/"
}

Gruntfile.js

module.exports = function(grunt) {
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        uglify: {
            simple: {
                files: {
                    '<%= pkg.destpath %>app.min.js': ['<%= pkg.srcpath %>app.js']
                }
            }
        } 
    });
    grunt.loadNpmTasks('grunt-contrib-uglify');
};

Command

grunt uglify

Puppy Three

Much Grunts

follow along at home: puppies/three/

package.json

{
    "name": "puppythree",
    "version": "0.1.0",
    "devDependencies": {
        "grunt": "~0.4.1",
        "grunt-contrib-less": "~0.8.1",
        "grunt-contrib-cssmin": "~0.6.2"
    },
    "srcpath": "src/",
    "destpath": "public/"
}

Gruntfile.js

module.exports = function(grunt) {
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        less: {
            simple: {
                files: {
                    '<%= pkg.srcpath %>css/bootstrap.css': [
                        '<%= pkg.srcpath %>less/bootstrap.less'
                    ]
                }
            }
        },
        cssmin: {
            simple: {
                files: {
                    '<%= pkg.destpath %>css/bootstrap.min.css': [
                        '<%= pkg.srcpath %>css/bootstrap.css'
                    ]
                }
            }
        }
    });
    grunt.loadNpmTasks('grunt-contrib-less');
    grunt.loadNpmTasks('grunt-contrib-cssmin');
    grunt.registerTask('default', ['less', 'cssmin']);
};

Command

grunt

Puppy Four

Super Specific Grunts

follow along at home: puppies/four/

(the important parts of) Gruntfile.js

uglify: {
    static: {
        files: {
            '<%= pkg.destpath %>js/base.min.js': [
                '<%= pkg.srcpath %>js/lib/jquery.js',
                '<%= pkg.srcpath %>js/lib/bootstrap.js'
            ]
        }
    },
    volatile: {
        files: {
            '<%= pkg.destpath %>js/app.min.js': [
                '<%= pkg.srcpath %>js/app.js'
            ]
        }
    }
}

Command

grunt uglify:static
grunt uglify:volatile

Puppy Five

NSA's Best Friend

follow along at home: puppies/five/

Watching

(the important parts of) Gruntfile.js

watch: {
    css: {
        tasks: ['less:volatile', 'cssmin:volatile'],
        files: [
            '<%= pkg.srcpath %>less/**', 
            '!<%= pkg.srcpath %>less/bootstrap/**'
        ]
    }
}

Command

grunt

Puppy Six

Hold On To Your Butts

follow along at home: puppies/six/ (if you dare)

Node.js at DeviantART

PHP + Node.js == Jenny Craig

Let's build our own

Grunt.js == Hunter

var hunter = require('./lib/hunter'),
hunted = hunter.hunt(grunt.config('pkg'));

List Files

We're in Node, let's use JSON

list/js/base.js.json

{
    "type": "static",
    "files": [
        "src/js/lib/jquery.js",
        "src/js/lib/underscore.js",
        "src/js/lib/backbone.js"
    ]
}

Set Config

Use hunted.js genertated by hunter.hunt() to tell uglify what to build and where to put it

grunt.config.set('uglify', hunted.js);

Confession:

This ended up being a bit too complicated.

Could do a whole talk just about Hunter

Slightly More Useful Things

Yeoman - Bower - Assemble

Yeoman

Scaffolding workflows

Bower

Kinda Package Management

Assemble

Static site generator for kids who are too cool for Jekyll

Questions?

You Suck At Explaining

Documentation from people who know way more than me (read: the people that wrote the damn things)