GruntJS The JavaScript Task Runner
What is Grunt? A build tool for JavaScript Uses Node to run A Gruntfile is actually just a JavaScript file Therefore, you can code directly in the Gruntfile
Getting Started with Grunt Must create a package.json file Has the following attributes: name version devDependencies You can use npm init or the grunt-init package to generate one For more optional attributes see { "name": "my-project-name", "version": "0.1.0", "devDependencies": { "grunt": "~0.4.2", "grunt-contrib-jshint": "~0.6.3", "grunt-contrib-jasmine": "~0.6.1", "grunt-contrib-uglify": "~0.2.2" }
Installing Grunt In the folder with package.json, run npm install This will install grunt, its dependencies, and any packages in devDependencies locally in that folder To add plugins later use npm install --save-dev This will update package.json and install the plugin
Writing a Gruntfile A Gruntfile is a JavaScript file with the following parts A wrapper function The config object Plugin loading Custom tasks module.exports = function(grunt) { // Project configuration. grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), uglify: { options: { banner: '/*! Hello*/\n' }, build: { src: 'src/.js', dest: 'build/.min.js' } }); // Load the plugin with the "uglify" task. grunt.loadNpmTasks('grunt-contrib-uglify'); // Default task(s). grunt.registerTask('default', ['uglify']); };
Grunt Plugins All tasks are provided by plugins A plugin is a node module A list can be found at contrib plugins are “official” Some plugins you might need are contrib-concat contrib-uglify contrib-jasmine contrib-yuidoc
Grunt Plugins All tasks are provided by plugins A plugin is a node module A list can be found at contrib plugins are “official” Install a plugin: npm install --save-dev Add grunt.loadNpmTasks( ) to your Gruntfile Some plugins you might need are contrib-concat contrib-uglify contrib-jasmine contrib-yuidoc
Setting Task Options Each plugin defines a task (or tasks) Tasks are named for the action they take (jasmine, concat, etc.) Each task can have multiple targets Targets are named however you like Options can be set at the task level or target level // Project configuration. grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), uglify: { options: { banner: '/*! */\n' }, dostuff: { src: 'src/.js', dest: 'build/.min.js', options: { wrap: true } });
File Options Options that specify files have several formats: src as a property of the target destination as the key with the source files as the value on a file object An array of objects with src/dest properties Can use *, **, ?, ! and {} for pattern matching mytarget:{ src: ['a.js', 'b.js'] dest: ['c.js'] } mytarget: { files: { 'output.js': ['src/*.js'], 'test_output.js': ['test/**/*.js'] } mytarget: { files: [ {src: ['a.js', 'b.js'], dest: 'c.js'}, {src: ['ii.js'], dest: 'i.js', filter: 'isFile'} ] }
The Jasmine Task This task runs Jasmine tests on the command line Important Options: src: the JavaScript files you are testing options.specs: your Jasmine testing specs options.template: the template for your HTML jasmine: { mytarget: { src: 'src/**/*.js', options: { specs: 'tests/*Spec.js', template: 'mytemplate.tmpl' }
Creating a Template The Jasmine plugin uses underscore You have a couple options: Generate all your HTML dynamically Create a template that adds Jasmine when a flag is passed Copy and paste your HTML into a template every time you change it Jasmine Spec Runner "> ">
Using YUIDoc YUIDoc parses tags in /** special comments */ Tags /** * Class description * MyClass */ /** * Method description * methodName {String} foo Argument 1 {Object} config A config object {String} config.name The name on the config object {Function} config.callback A callback function on the config object {Boolean} [extra=false] Do extra, optional work {Boolean} Returns true on success */ /** * Property description. * propertyName {Object} "foo" */
YUIDoc is for a collection of related classes Must have at least one per source is for a function that generates an object or includes events You must have at least one per is for a function on an is for a callback The others give additional information about each of these
The YUIDoc Task The only important options are paths and outdir The rest just help the document look pretty. grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), yuidoc: { mytarget: { name: ' ', description: ' ', version: ' ', url: ' ', options: { paths: 'path/to/source/code/', outdir: 'where/to/save/docs/' } });
Exercise 1.Download demo.tar from the website (or copy it from /var/www/html on the server) 2.Copy Gruntfile.js and package.json to your own project 3.Run npm install to install grunt and the necessary plugins 4.Modify the grunt file to do something with your application