Grunt

Kevin Kazmierczak

Sencha Practice Director | @kazmiekr
kevin.kazmierczak@universalmind.com

Javascript Task Runner

  • Automation
  • Things like:
    • Minification
    • Unit Testing
    • Linting
    • Sass/Less compilation

Ecosystem

Getting Started

npm install -g grunt-cli

Doesn’t install the runner itself, runs the version of Grunt installed next to the Gruntfile

Setup

  • package.json - Defines all your dependencies
  • Gruntfile.js - Defines your tasks

Installing Grunt and Plugins

npm install grunt --save-dev

--save-dev will automatically add the installed package to your local package.json file

Popular Plugins

  • CoffeeScript
  • Less
  • Sass
  • JSHint
  • RequireJS
  • Handlebars
  • ~2300 available plugins

Define Tasks


module.exports = function(grunt) {
	// Project configuration.
	grunt.initConfig( {
	    pkg: grunt.file.readJSON('package.json'),
	    uglify: {
	        options: {
	            banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'
	        },
	        build: {
	            src: 'src/<%= pkg.name %>.js',
	            dest: 'build/<%= pkg.name %>.min.js'
	        }
	    }
	});
	// Load the plugin that provides the "uglify" task.
	grunt.loadNpmTasks('grunt-contrib-uglify');
	// Default task(s).
	grunt.registerTask('default', ['uglify']);
};
					

Multiple Task Targets


grunt.initConfig({
  concat: {
    foo: {
      // concat task "foo" target options and files go here.
    },
    bar: {
      // concat task "bar" target options and files go here.
    },
  },
  uglify: {
    bar: {
      // uglify task "bar" target options and files go here.
    },
  },
});
					

Options


grunt.initConfig({
  concat: {
    options: {
      // Task-level options may go here, overriding task defaults.
    },
    foo: {
      options: {
        // "foo" target options may go here, overriding task-level options.
      },
    },
    bar: {
      // No options specified; this target will use task-level options.
    },
  },
});
					

Write your own tasks


grunt.registerTask('foo', 'A sample task that logs stuff.', function(arg1, arg2) {
  if (arguments.length === 0) {
    grunt.log.writeln(this.name + ", no args");
  } else {
    grunt.log.writeln(this.name + ", " + arg1 + " " + arg2);
  }
});
					

Register them with npm with a ‘gruntplugin’ keyword

Real World Sample

  • Deployment Build
    • Generates a sprite sheet from a folder of sprites
    • Compiles our Less
    • Builds our RequireJS modules
    • Posts an OSX notification to indicate success/failure
  • Watcher
    • The first two run on any save to a *.less file or new asset in sprites folder

Grunt Resources

Gulp

Gulp

http://gulpjs.com/

Gulp

  • Code over configuration
  • Use streaming
  • Basic Node module syntax

Setup


npm install -g gulp
npm install --save-dev gulp gulp-util
						
  • Create a gulpfile.js
  • gulp

Sample Gulpfile


var gulp = require('gulp');
var coffee = require('gulp-coffee');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var paths = {
  scripts: ['client/js/**/*.coffee', '!client/external/**/*.coffee'],
  images: 'client/img/**/*'
};

gulp.task('scripts', function() {
  // Minify and copy all JavaScript (except vendor scripts)
  return gulp.src(paths.scripts)
    .pipe(coffee())
    .pipe(uglify())
    .pipe(concat('all.min.js'))
    .pipe(gulp.dest('build/js'));
});
					

Questions