Grunt Tutorial

advertisement
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
{
"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"
}
• 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
https://npmjs.org/doc/json.html
}
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
<module-name> --save-dev
• This will update package.json and install
the plugin
Writing a Gruntfile
module.exports = function(grunt) {
• A Gruntfile is a JavaScript
file with the following
parts
•
•
•
•
A wrapper function
The config object
Plugin loading
Custom tasks
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
uglify: {
options: {
banner: '/*! Hello*/\n'
},
build: {
src: 'src/<%= pkg.name %>.js',
dest: 'build/<%= pkg.name %>.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 http://gruntjs.com/plugins
• 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
http://gruntjs.com/plugins
• contrib plugins are “official”
• Install a plugin:
• npm install <plugin> --save-dev
• Add
grunt.loadNpmTasks(<plugin>)
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: '/*! <%= pkg.name %> */\n'
},
dostuff: {
src: 'src/<%= pkg.name %>.js',
dest: 'build/<%= pkg.name %>.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
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Jasmine Spec Runner</title>
<% css.forEach(function(style){ %>
<link rel="stylesheet" type="text/css" href="<%= style %>">
<% }) %>
<% with (scripts) { %>
<% [].concat(polyfills, jasmine, boot, vendor, helpers, src,
specs,reporters).forEach(function(script){ %>
<script src="<%= script %>"></script>
<% }) %>
<% }; %>
</head>
<body>
</body>
</html>
Using YUIDoc
• YUIDoc parses tags in /**
special comments */
• Tags start with @
•
•
•
•
•
•
•
@class
@method
@event
@param
@property
@type
@default
/**
* Class description
*
* @class MyClass
* @constructor
*/
/**
* Method description
*
* @method methodName
* @param {String} foo Argument 1
* @param {Object} config A config object
* @param {String} config.name The name on the config object
* @param {Function} config.callback A callback function on the
config object
* @param {Boolean} [extra=false] Do extra, optional work
* @return {Boolean} Returns true on success
*/
/**
* Property description.
*
* @property propertyName
* @type {Object}
* @default "foo"
*/
YUIDoc Tags
• @module is for a collection of related classes
• Must have at least one per source tree
• @class is for a function that generates an object or includes
events
• You must have at least one per file
• @method is for a function on an object
• @event 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: '<%= pkg.name %>',
description: '<%= pkg.description %>',
version: '<%= pkg.version %>',
url: '<%= pkg.homepage %>',
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
Download