All Articles

Introduction to GruntJS

Which developer never wasted time doing repetitive and boring tasks instead of being focused on what we do best “Code”.

Developers should be worry about write code but very often we got ourself doing a lot of repetitive and boring tasks like cleaning the code, minifying, combining, generating and so on so forth.

How many time would you save not doing those tasks? today I will show you the introduction use to help you on your daily bases development work flow.

There’s a answer and it’s called GruntJS I have been using a while and I got say “It’s true love” I can watch for changes on my files, run tests, minify, pre-process SASS, minify images and the list goes on take at look on the plugins at GruntJS plugins and for more information and further reference you MUST go to GruntJS website.

Let’s say we want to watch for changes on the js files and HTML markup minify both and concatenate all js files in one single file.

Let’s get start

Create a folder on your desktop (or whatever you want to) and let’s call it GruntJS-app.
Add this follow simple architecture to your project.

  • GruntJS-app
    — dist // html destination
    — src // html source
    --- index.html
    --- internal.html
    — assets
    --- js
    ---- main.js
    ---- app.js
    ---- module.js
    --- css
    --- images

Then you will need NodeJS if you don’t have go to the NodeJS website for installation information.

To make GruntJS work properly you will need some two specific files “package.json” used by npm contain the information for the project where you list grunt and plugins used by your project as “devDependencies” and the “Gruntfile.js” where you set your tasks to run.

So let’s add to the project GruntJS-app

  • GruntJS-app
    — dist // html destination
    — src // html source
    --- index.html
    --- internal.html
    — assets
    --- js
    ---- main.js
    ---- app.js
    ---- module.js
    --- css
    --- images
    — package.json // added new file
    — Gruntfile.js // added new file

Installing GruntJS

On your root project folder run the command line

sudo npm install -g grunt-cli

Now you have the grunt command line installed globally to your project

Configuring GruntJS (Gruntfile.js)

the basic structure to configure your Gruntfile.js file is simple.

module.exports = function(grunt) {

	grunt.initConfig({
		
	});

}

Configuring the package.json

You can add tons of information on you package json and you can check all information here but in this case let’s keep it as simple as possible.


{
	"name": "GruntJS-app",
	"title": "GruntJS-app",
	"description": "Simple introduction to GruntJS set up",
	"author": "your name",
	"homepage": "your project website",
	"version": "0.0.1",
	"devDependencies": {
		"grunt": "~0.4.1"
	}
}
```

## Adding plugins to use as task

Remember that we want to "watch" for changes minify both HTML, js files and concatenate all js files in one single file

Now on you wont need to go manually to package.json to add the plugins as devDependencies because you are going to run the command on your terminal to add it automatically.

First let's install Uglify

```ruby
npm install grunt-contrib-uglify --save-dev
```

And enable the plugin inside of Gruntfile.js

```javascript
grunt.loadNpmTasks('grunt-contrib-uglify');
```

Now Gruntfile.js looks like this

```javascript
module.exports = function(grunt) {

	grunt.initConfig({

	});

	grunt.loadNpmTasks('grunt-contrib-uglify');

}
```

Install htmlmin

```ruby
npm install grunt-contrib-htmlmin --save-dev
```

Enable the plugin

```javascript
grunt.loadNpmTasks('grunt-contrib-htmlmin');
```

Now Gruntfile.js looks like this

```javascript
module.exports = function(grunt) {

	grunt.initConfig({

	});

	grunt.loadNpmTasks('grunt-contrib-uglify');
	grunt.loadNpmTasks('grunt-contrib-htmlmin');

}
```

## Setting the tasks

On your Gruntfile.js you will define the configuration for your tasks (check out the plugins documentation for configuration) as should be and the task register.

```javascript
module.exports = function(grunt) {

	grunt.initConfig({

		uglify: {
			my_target: {
		      files: {
		        'assets/js/app.min.js': // destination
		        ['assets/js/app.js', 'assets/js/main.js', 'assets/js/module.js'] // source
		      }
		    }
		},

		htmlmin: {
			dist: {
		  		options: {
		    	removeComments: true,
		    	collapseWhitespace: true
		  	},
		  	files: {
		    		'dist/index.html': 'src/index.html', // destination
					'dist/internal.html': 'src/internal.html' // source
				}
			}
		}

	});

	grunt.loadNpmTasks('grunt-contrib-uglify');
	grunt.loadNpmTasks('grunt-contrib-htmlmin');

	grunt.registerTask('build', ['htmlmin', 'uglify']);

}
```

## Running the tasks

Make sure you have all the npm installed

```ruby
npm install
```

Run the task

```ruby
grunt build
```

Done! This is what you should have as a response.

```ruby
Running "htmlmin:dist" (htmlmin) task
File dist/index.html created.
File dist/internal.html created.

Running "uglify:my_target" (uglify) task
File "assets/js/app.min.js" created.

Done, without errors.
```

## Adding and configuring watch

Remember "no waste of time" with repetitive tasks right? so to not need run "grunt build" every time after changes let's add the plugin watch.

Install watch

```ruby
npm install grunt-contrib-watch --save-dev
```

Enable the plugin and configure the watch task

```javascript
grunt.loadNpmTasks('grunt-contrib-watch');

grunt.event.on('watch', function(action, filepath) {
  grunt.log.writeln(filepath + ' has ' + action);
});
```

Now Gruntfile.js looks like this (check out the plugin documentation for configuration).

```javascript
module.exports = function(grunt) {

	grunt.initConfig({

		uglify: {
			my_target: {
		      files: {
		        'assets/js/app.min.js': // destination
		        ['assets/js/app.js', 'assets/js/main.js', 'assets/js/module.js'] // source
		      }
		    }
		},

		htmlmin: {
			dist: {
		  		options: {
		    	removeComments: true,
		    	collapseWhitespace: true
		  	},
		  	files: {
		    		'dist/index.html': 'src/index.html', // destination
					'dist/internal.html': 'src/internal.html' // source
				}
			}
		},

		watch: {
		    src: {
		      files: ['src/*.html', 'assets/js/*.js', 'assets/css/*.css', '!assets/js/app.min.js'], // ! means not
		      tasks: ['build'],
		    },
		}

	});

	grunt.loadNpmTasks('grunt-contrib-uglify');
	grunt.loadNpmTasks('grunt-contrib-htmlmin');
	grunt.loadNpmTasks('grunt-contrib-watch');

	grunt.registerTask('build', ['htmlmin', 'uglify']);

	grunt.event.on('watch', function(action, filepath) {
	  grunt.log.writeln(filepath + ' has ' + action);
	});

}
```

Now on you will just need to run "grunt watch" so every time you change something in the files set up to watch will run the task "build"

```ruby
grunt watch
```

and this is what you should see after run the command

```ruby
Running "watch" task
Waiting...
```

To stop watch press "control + c" 

## Conclusion

GruntJS is AWESOME and you can do much more complex things with it.

Check out the example on Github. Now you have more time to play with new experiments.
Cheers!
Published 1 Jun 2013

Software Engineer focused in Javascript applications
Michael Lancaster on Twitter