Thursday, May 1, 2014

Basics of Grunt: A task runner that helps automate your bulid-processes in your web development project



This blog covers couple of "elementary" use-cases for Grunt task runner. That is to automate certain repetitive build-processes in your project. Here the build-processes refers to invoking transpiler, JavaScript files concatenation & its minification.
Presumptions:
  • CoffeeScript is used instead of regular JavaScript in your web development project
  • Node.js runtime is installed
  • npm package manager for Node.js is also installed
Table of contents

Grunt task runner installation

Running the below command will install Grunt globally (i.e. accessible to Node.js runtime):
$ sudo npm install grunt-cli -g


Use-case 1

Grunt task runner for automating transpilation


i. Create source code folders

Starting with an empty project folder, create these two folders in your project's root directory:
  • js
  • coffeescript

ii. Install Grunt into your project

In your project's root folder, run the below command:
$ npm install grunt

iii. Generate 'package.json' file

This 'package.json' is required by the npm package manager. Now, run the below command & answer the project related meta-data as you find fit:
$ npm init

iv. Create 'Gruntfile.js' file

Now, in the project's root folder, create the must needed 'Gruntfile.js' file, with following modules definition skeleton:
module.exports = function(grunt) {
    grunt.initConfig({});
    grunt.loadNpmTasks();
};

v. Install & configure CoffeeScript-to-JavaScript transpiler module

Now, with the help of npm, we install a Grunt module for CoffeeScript-to-JS transpilation, with the below command:
$ npm install grunt-contrib-coffee --save-dev
Now, in the above created 'Gruntfile.js' file add the following module-handling definitions:
module.exports = function(grunt) {
    grunt.initConfig({
        coffee: {
            options: {
                bare: true
            },
            scritps: {
               expand: true,
               flatten: true,
               cwd: 'coffeescript/',
               src: ['*.coffee'],
               dest: 'js/',
               ext: '.js'
            }
        }
    });

    grunt.loadNpmTasks('grunt-contrib-coffee');
};
Now, in-order to run the transpiler against your project's CoffeeScript, run the below command:
$ grunt coffee

vi. Automate transpilation

Now, the following two steps are necessary to automate-the-invocation of CoffeeScript-to-JS transpiler:
NOTE! This transpilation takes place only for the modified source files by Grunt.
Step1: Install modules that help in auto-running
Install these modules 'grunt-contrib-watch' & 'grunt-newer' with the below command:
$ npm install grunt-contrib-watch grunt-newer --save-dev
Step2: Configure Gruntfile.js file
Add the below definitions to 'Gruntfile.js' file:
module.exports = function(grunt) {
    grunt.initConfig({
        coffee: {
            options: {
                bare: true
            },
            scritps: {
                expand: true,
                flatten: true,
                cwd: 'coffeescript/',
                src: ['*.coffee'],
                dest: 'js/',
                ext: '.js'
            }
        },
        watch: {
            options: {
                livereload: true
            },
            scritps: {
                files: ['coffeescript/*.coffee'],
                tasks: ['newer:coffee']
            }
       }
    });

    grunt.loadNpmTasks('grunt-contrib-coffee');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-newer');
};
Now, in-order to auto-run the transpiler against your project's CoffeeScript, run the below command:
$ grunt watch


Use-case 2

Grunt task runner for automating concatenation & minification


i. Create a distribution folder

Now, in the project's root folder, create the below folder:
  • distribution

ii. Install & configure Concatenation & Minification modules

Now, with the help of npm, install the below two Grunt modules. These modules can concatenate JS files into a single-file & minify it. So, in-order to install these two modules run this command:
$ npm install grunt-contrib-concat grunt-contrib-uglify --save-dev
Add the below definitions to 'Gruntfile.js' file:
module.exports = function(grunt) {
    grunt.initConfig({
        coffee: {
            options: {
                bare: true
            },
            scritps: {
               expand: true,
               flatten: true,
               cwd: 'coffeescript/',
               src: ['*.coffee'],
               dest: 'js/',
               ext: '.js'
            }
        },
        watch: {
            options: {
                livereload: true
            },
            scritps: {
                files: ['coffeescript/*.coffee'],
                tasks: ['newer:coffee']
            }
        },
        concat: {
            dist: {
                src: ['js/*.js'],
                dest: 'distribution/js/all.js'
            }
        },
        uglify: {
            dist: {
                options: {
                    banner: '/* Project-Template Shaped With Grunt Task Runner by Nash | May 2014 */\n'
                },
                files: {
                    'distribution/js/all.min.js': ['distribution/js/all.js']
                }
            }
        }
    });

    grunt.loadNpmTasks('grunt-contrib-coffee');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-newer');
    grunt.loadNpmTasks('grunt-contrib-concat');
    grunt.loadNpmTasks('grunt-contrib-uglify');
};
Validate the above definitions does work by running these commands:
$ grunt concat
$ grunt uglify

iii. Automate build-sequence

Now, automating the invocation of the following build-sequence by Grunt: Transpilation-> Concatenation-> Minification of source files.
Configure Gruntfile.js file
Add the below definitions to 'Gruntfile.js' file in-order help setup the build-sequence:
module.exports = function(grunt) {
    grunt.initConfig({
        coffee: {
            options: {
                bare: true
            },
            scritps: {
               expand: true,
               flatten: true,
               cwd: 'coffeescript/',
               src: ['*.coffee'],
               dest: 'js/',
               ext: '.js'
            }
        },
        watch: {
            options: {
                livereload: true
            },
            scritps: {
                files: ['coffeescript/*.coffee'],
                tasks: ['autobuild-with-minification']
            }
        },
        concat: {
            dist: {
                src: ['js/*.js'],
                dest: 'distribution/js/all.js'
            }
        },
        uglify: {
            dist: {
                options: {
                    banner: '/* Project-Template Shaped With Grunt Task Runner by Nash | May 2014 */\n'
                },
                files: {
                    'distribution/js/all.min.js': ['distribution/js/all.js']
                }
            }
        }
    });

    grunt.loadNpmTasks('grunt-contrib-coffee');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-newer');
    grunt.loadNpmTasks('grunt-contrib-concat');
    grunt.loadNpmTasks('grunt-contrib-uglify');

    grunt.registerTask('autobuild-with-minification', ['newer:coffee', 'concat', 'uglify']);
    grunt.registerTask('default', ['coffee', 'concat', 'uglify', 'watch']);
};
Now, in-order to auto-run build-sequence, such as Transpilation-> Concatenation-> Minification, run the below command:
$ grunt
NOTE! You can further minify your JS file, if your 'Gruntfile.js' definition does not include this definition under 'coffee':
options: {
   bare: true
}


External references

No comments:

Post a Comment