Our website is made possible by displaying online advertisements to our visitors. Please consider supporting us by disabling your ad blocker.

Use Grunt To Lint And Uglify Your JavaScript Project

TwitterFacebookRedditLinkedInHacker News

JavaScript is a forgiving language unlike Java or C#. Because of this, we can’t always trust that our code is correct. I don’t mean that the logic may not be correct, I’m talking about syntax and structure.

Lint via Wikipedia:

…modern lint checkers are often used to find code that doesn’t correspond to certain style guidelines. They can also be used as simple debuggers for common errors, or hard to find errors such as heisenbugs

In addition to needing to lint your code for errors, you may also consider compressing and obfuscating your source code. This can be done through the process of uglification or minification.

Minification via Wikipedia:

Minification (also minimisation or minimization), in computer programming languages and especially JavaScript, is the process of removing all unnecessary characters from source code without changing its functionality.

Linting and minification are two tasks that can easily be run with a task runner such as Grunt or Gulp. In this example, I’ll be demonstrating how to use Grunt to run these tasks.

Grunt can be installed with the Node Package Manager (NPM) as well as all its dependencies. At this point, I’m going to assume you’ve already installed Node.js and NPM.

Let’s start by installing the Grunt CLI:

npm install -g grunt-cli

Grunt operates off a Gruntfile.js file that must be placed at the root of your project next to your package.json file. All Grunt dependencies will be found in the package.json file and all tasks will be found in the Gruntfile.js file.

For this example, our file and directory structure will look like the following:

Gruntfile.js
package.json
example.js
example.min.js *

Notice the asterisk (*) I put next to the example.min.js file. I did this, because this is a file that will be generated via Grunt, not a file that we manually create. In other words, do not create example.min.js in your project directory.

Inside your package.json file, add the following:

{
    "name": "example",
    "version": "0.0.1",
    "description": "This is an example to show how Grunt works",
    "author": {
        "name": "Nic Raboy",
        "url": "http://www.nraboy.com"
    },
    "homepage": "https://www.thepolyglotdeveloper.com",
    "devDependencies": {
        "grunt": "~0.4.5",
        "grunt-contrib-jshint": "~0.10.0",
        "grunt-contrib-clean": "~0.6.0",
        "grunt-contrib-uglify": "~0.5.0"
    },
    "keywords": [
        "javascript",
        "demo",
        "task runner"
    ],
    "license": "MIT"
}

Notice lines in the above JSON file. These are the Grunt dependencies that we’ll use. They include grunt, jshint, clean, and uglify.

Now crack open your Gruntfile.js file and include the following code:

module.exports = function(grunt) {

    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        uglify: {
            options: {
                banner: '// <%= pkg.name %> - v<%= pkg.version %> (<%= grunt.template.today("yyyy-mm-dd") %>)\n' + '// https://www.nraboy.com\n'
            },
            build: {
                src: '<%= pkg.name %>.js',
                dest: '<%= pkg.name %>.min.js'
            }
        },
        jshint: {
            all: ['*.js']
        },
        clean: {
            js: ['*.min.js']
        }
    });

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

    grunt.registerTask('default', ['clean', 'jshint', 'uglify']);

};

I’m going to explain the above code from bottom to top since it should be easier to understand that way.

The registerTask for default will run clean, jshint, and uglify in that order when typing grunt into the command line. If you were to use a task name other than default, you would run it by doing grunt taskname from the command line.

You can see above registerTask we load all the Grunt tasks for use with loadNpmTasks. Again, in our scenario we are strictly staying with clean, jshint, and uglify.

Finally we get to where all the magic happens. The initConfig is how we configure each module and define what we want it to do.

clean: {
    js: ['*.min.js']
}

In the above code we are telling clean that we want to remove all min.js files from the root of our project. In our example project, the only file that will meet this filter is the example.min.js file that will be created after each run. We want to clean it before rebuilding to avoid any kind of file corruption from concatenated data.

jshint: {
    all: ['*.js']
}

In the above code we are telling jshint to lint all JavaScript files at the root of our project. This would have included example.min.js if we hadn’t cleaned it first.

uglify: {
    options: {
        banner: '// <%= pkg.name %> - v<%= pkg.version %> (<%= grunt.template.today("yyyy-mm-dd") %>)\n' + '// https://www.nraboy.com\n'
    },
    build: {
        src: '<%= pkg.name %>.js',
        dest: '<%= pkg.name %>.min.js'
    }
}

The above code is the final of our three tasks. Options and build parameters can be passed into this module. In our example, we are creating a comment banner that will be on the first line of our uglified code. The pkg variables are read from our package.json file. The build instructions are to take example.js as the source file and produce example.min.js as the destination file.

It is important to note that if any task fails, Grunt will abort and not run any following tasks.

At this point, it is time to create a simple JavaScript file to run against Grunt. Open your example.js file and add the following:

var add = function(value1, value2) {
    var sum = value1 + value2;
    return sum;
}

We are not ready to test this yet. First we need to install all the NPM dependencies with npm install.

With everything installed run the following from the command line:

grunt

You should notice a lint error like this:

Grunt Lint Error

We got this error because we didn’t add a semicolon after creating our add variable. Fixing this and running again should result in no errors, but instead a new example.min.js file. Inside this file it should look like this:

// example - v0.0.1 (2014-11-26)
// http://www.nraboy.com
var add=function(a,b){var c=a+b;return c};

Notice that the variables were obfuscated and minified? This is exactly what we wanted.

By making use of Grunt, as well as a lint and uglification utility, you’re code should be greatly improved from a performance perspective as well as a quality perspective.

Nic Raboy

Nic Raboy

Nic Raboy is an advocate of modern web and mobile development technologies. He has experience in C#, JavaScript, Golang and a variety of frameworks such as Angular, NativeScript, and Unity. Nic writes about his development experiences related to making web and mobile development easier to understand.