X

Using Grunt JavaScript Uglify and Concat

Grunt

Using Grunt JavaScript Minification

We will continue from our last blog post on Grunt: using less and css minification to JavaScript minification using a plugin called Uglify.

JSHint

To begin we will use a linting tool called jshint, to help us in taming our JavaScript with some static code analysis to flags suspicious usage.

We can use the command line npm install for it or we can use the visual studio tool to install

npm install grunt-contrib-jshint --save-dev

Npm JsHint

Now that we have jshint lets add our grunt task for jshint in our Gruntfile.js

module.exports = function (grunt) {
    grunt.initConfig({
    
        cssmin: {
            target: {
                files: {
                    'deploy/style.min.css': 'public/stylesheets/mystyle.css'
                }
            }
        },

        less: {
            compile: {
                files: {
                    'deploy/compiled.css': 'public/stylesheets/layout.less'
                }
            }
        },

        jshint: {
            jsFiles: ['public/javascripts/**/*.js']                             
        }
    });
    
    // Next one would load plugins
    grunt.loadNpmTasks('grunt-contrib-cssmin');
    grunt.loadNpmTasks('grunt-contrib-less');
    grunt.loadNpmTasks('grunt-contrib-jshint');

    // Here is where we would define our task
    grunt.registerTask('default', ['cssmin:target', 'less:compile', 'jshint:jsFiles']);
};

You may realize that something different in our jshint section, there are some ** inside the file name. The pattern of /**/ basically mean traverse through all the children levels of the directory hierarchy, and the *.js means all the file with extension of js. By doing so, our script will always scan through any subdirectory for any future js files we may add.

Lets add a file inside of public/javascripts/ directory and call it myapp.js, our file will look something like this.

"use-strict";
var myapp = {};

myapp.name = 'This is a sample app';

myapp.isNull = function (a) {    
    return a == null;
};

When we run our task using TaskRunner in Visual Studio or command line for jshint, we will get back a fail task and some suggestion on our JavaScript.

$ grunt jshint:jsFiles

//output
Running jshint:jsFiles (jshint) task

   public\javascripts\myapp.js
      7 |    return a == null;
                      ^ Use '===' to compare with 'null'.

1 error in 1 file

Aborted due to warnings.
Process terminated with code 3.

In order to fix the script jshint already suggest us to use the “===” for compare. Let’s now add another file called myapp2.js and also fix our myapp.js file.

"use-strict" ;

var myapp2 = {};

myapp2.sayHello = function () {
    return "Hello";
};

When we rerun our task we should have no more errors.

$ grunt jshint:jsFiles
>> 2 files lint free.

Done, without errors.

Concat

We will now like to concat the file together and there is yet another plugin for grunt to concat files for us grunt-contrib-concat, as always we can use the npm tool in visual studio or the command line to install it.

$ npm install grunt-contrib-concat --save-dev

And in our Gruntfile.js we will add our concat task

module.exports = function (grunt) {
    grunt.initConfig({
    
        cssmin: {
            target: {
                files: {
                    'deploy/style.min.css': 'public/stylesheets/mystyle.css'
                }
            }
        },

        less: {
            compile: {
                files: {
                    'deploy/compiled.css': 'public/stylesheets/layout.less'
                }
            }
        },

        jshint: {
            jsFiles: ['public/javascripts/**/*.js']                             
        },

        concat: {
            js: {
                files: {'deploy/bundle.js': 'public/javascripts/**/*.js' }
            }
        }
    });
    
    // Next one would load plugins
    grunt.loadNpmTasks('grunt-contrib-cssmin');
    grunt.loadNpmTasks('grunt-contrib-less');
    grunt.loadNpmTasks('grunt-contrib-jshint');
    grunt.loadNpmTasks('grunt-contrib-concat');

    // Here is where we would define our task
    grunt.registerTask('default', ['cssmin:target', 'less:compile', 'jshint:jsFiles', 'concat:js']);
};

From the script we will see that it will add the bundle.js file into the deploy directory.

bundle.js

and if we open the file, we will see that both scripts are combined into one file.

concat

Uglify

Lastly, we would like to uglify the file, as in minification of the Javascript files. As always we will install our plugin and modify our Gruntfile.

$ npm install grunt-contrib-uglify --save-dev

Our new Gruntfile.js would look like

module.exports = function (grunt) {
    grunt.initConfig({
    
        cssmin: {
            target: {
                files: {
                    'deploy/style.min.css': 'public/stylesheets/mystyle.css'
                }
            }
        },

        less: {
            compile: {
                files: {
                    'deploy/compiled.css': 'public/stylesheets/layout.less'
                }
            }
        },

        jshint: {
            jsFiles: ['public/javascripts/**/*.js']                             
        },

        concat: {
            js: {
                files: {'deploy/bundle.js': 'public/javascripts/**/*.js' }
            }
        },

        uglify: {
            bundle: {
                files: {'deploy/bundle.min.js': 'deploy/bundle.js'}
            }
        }
    });
    
    // Next one would load plugins
    grunt.loadNpmTasks('grunt-contrib-cssmin');
    grunt.loadNpmTasks('grunt-contrib-less');
    grunt.loadNpmTasks('grunt-contrib-jshint');
    grunt.loadNpmTasks('grunt-contrib-concat');
    grunt.loadNpmTasks('grunt-contrib-uglify');

    // Here is where we would define our task
    grunt.registerTask('default', ['cssmin:target', 'less:compile', 'jshint:jsFiles', 'concat:js', 'uglify:bundle']);
};

uglify

And now our bundle.min.js file is a minified javascript file (Uglified).

minified

Summary

In this post we covered quite an area of grunt where we used multiple plugins to accomplish javascript related task (minification, concat, etc), in the next post we use grunt to automate our testing and clean up task.

Taswar Bhatti:
Related Post