2. Grunt - Introduction
On these slides I will show you how to master the GruntJS Task Runner program with
example and cross references to a github project.
Grunt is a way to automate operations and to performing repetitive tasks. After the
"configuration" grunt will help you in repetive tasks like minification, compiling, unitest,
etc.
The configuration of GruntJS begins writing the Gruntfile.js file, inside this file we will
define the operations that we need and their dependencies.
3. Gruntfile.js
module.exports = function (grunt) {
//area 1 - loadding modules
grunt.loadNpmTasks('grunt-contrib-clean');
//area 2 - configure single plugins
grunt.initConfig({
clean: {
'static': ['static/*'],
},
});
//area 3 - register the operations deps
grunt.registerTask('default', ['clean']);
};
The Gruntfile.js by side show the three main session of
the grunt configuration file.
Saving it inside a directory that execute the following
command in the same directory:
$ npm install grunt-contrib-clean --save-dev
$ grunt
The grunt call will show you something like:
$ grunt
Running "clean:static" (clean) task
Done, without errors.
Here we just execute the default registered task defined
inside the third area of the Gruntfile.js, task that is
composed by an array of subsequential operation in this
case the single operation "clean:static"
4. Grunfile.js
module.exports = function (grunt) {
//area 1 - loadding modules
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-contrib-concat');
//area 2 - configure single modules
grunt.initConfig({
clean: {
'static': ['static/*']
},
concat: {
homepage: {
src: ['head.html', 'body.html', 'footer.html'],
dest: 'static/index.html'
}
}
});
//area 3 - register the operations deps
grunt.registerTask('default', ['clean', 'concat']);
};
Grunt is generally extended using plugins, and in this
second example we load two plugins from the npm
repository; to run this example you should run:
$ npm install grunt-contrib-concat --save-dev
This particular plugin is used to concatenate files, a
common operation that generally is used agains js files
but here it is show agains some html files.
The resulting should be:
$ grunt
Running "clean:static" (clean) task
Running "concat:homepage" (concat) task
File "static/index.html" created.
Done, without errors.
This result in a new empty index.html file inside static/
5. webserver
Workflow with grunt
Grunt is generally used as developer helper tools
that made tasks meanwhile the developer is
coding his app.
A tipical workflow is show by side.
Grunt will manipulate some input files with a
series of task and generate the staging files on
witch the developer can do is work.
In the follow slides I will show you a typical use
case where we use grunt to operate
automatically over some javascript files and html
file using minification and webserver.
htmls
files
js
files
grunt
staging
files
6. A simple workflow
module.exports = function (grunt) {
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-connect');
grunt.initConfig({
clean: {
'static': ['static/*']
},
concat: {
homepage: {
src: ['head.html', 'body.html', 'footer.html'],
dest: 'static/index.html'
},
js: {
src: ['lib/*.js', 'my-app.js'],
dest: 'static/app.js'
}
},
connect: {
dev: {
options: {
//point your browser to http://localhost:9000
port: 9000,
base: 'static/'
}
}
}
});
grunt.registerTask('default', ['clean', 'concat', 'connect']);
};
Be side is show a workflow compliant with the previous
slide. Files are manipulated than an instance of connect.
js is executed and you can see the resulting webapp on
port 9000.
Should be clear now that the use this example you
should install some grunt plugins using npm.
Here you should install grunt-contrib-connect using this
command:
$ npm install grunt-contrib-connect --save-dev
What's happen if the developer modify the my-app.js file?
How to automate the update of files?
7. webserver
Workflow with grunt-watch
The grunt-wacth plugin is used to run some
tasks when files changes, tipically it is used to
run specific tasks when some kinds of files are
modified.
For example if some js files is modified we can
lint, concat and minify all the js files togheter.
Image this situation, the developer is writting his
code, save the project files and grunt will operate
individually meanwhile the developer is switching
from his code editor to the browser.
BIG WIN!
Let see this gruntfile in detail.
htmls
files
js
files
grunt
staging
files
grunt-watch
8. A workflow with watch
watch: {
webapp: {
files: [ 'libs/*.js' , 'my-app.js' ],
tasks: [ 'concat:js' ]
},
html: {
files: [ '*.html'],
tasks: [ 'concat:homepage' ]
}
}
});
//in area 3
grunt.registerTask( 'default', ['clean', 'concat', 'connect', 'watch']);
To integrate the previous
Gruntfile with the watch
improvment you should add the
piece of code be side inside the
initConfig object.
Please note how different
changes to files triggers different
group of tasks.
Now you can dev your using
app with livereload.
connect is serving the pages in process watch will waiting for changes
based on file type call the
appropriate sub-task
9. Custom task
You can also write a custom grunt task that is defacto a javascript
function execute inside nodejs enviroment (as grunt itself)
grunt.task.registerTask( 'config', 'compile config from config.js ' , function () {
var fs = require( 'fs');
var config = require( 'config');
if (!fs.existsSync( 'config.json' )) {
fs.writeFileSync( 'config.json' , JSON.stringify(config, null, 2));
}
});
grunt.registerTask( 'default', ['clean', 'config', 'concat', 'watch']);
Here you can see a custom task that generate a config.json file
using the nodejs fs api.
10. Grunt plugins
Grunt plugins are great to extend and personalize the use of grunt
and you can also write your own plugins using the powerful grunt
api.
If you need to write a plugin I would suggest to start from the task
api and than read at least the files api before start.
11. Integrate grunt plugins
On http://gruntjs.com/plugins you can found more that 2600 plugin
right now.
Go and explore this new world!