Skip to content
Home » Getting started with Grunt – The JavaScript Task Runner

Getting started with Grunt – The JavaScript Task Runner

grunt js
  1. What is Grunt:
    • Grunt.js is a JavaScript task runner that helps to perform repetitive tasks such as:
      • CSS Preprocessing.
      • JavaScript linting.
      • Unit Testing.
      • Image optimization.
      • Minification of JS and CSS files.
      • Concatenating files.
      • Reloading the browser etc.
  2. Installing Grunt:
    • It’s a command line utility.
    • It uses Node.js and installed via npm so it requires node and npm.
    • Command to install Grunt:
      npm install -g grunt-cli
      (-g is if you want to use it as a command line tool)
      On successful installation, it will put the grunt command in your system path allowing it to be run from any directory.
    • You can check the grunt version and installation confirmation by running: grunt --version.
  3. How it works:
    • Each time grunt is run, it looks for a locally installed Grunt using node’s require() system. and with this, you can run grunt from any subfolder in your project.
      If a locally installed Grunt is found, the CLI loads the local installation of the Grunt library, applies the configuration from your Gruntfile, and executes any tasks you’ve requested for it to run.
    • Grunt setup requires two file that is package.json and a Gruntfile named Gruntfile.js.
  4. Grunt setup needs: package.json:
    • This file is used by npm to store metadata for projects published as npm modules.
    • This JSON file enables us to track and install all of our development dependencies.
    • Below is a sample package.json having dependencies as grunt plugins which we will use for our demo so create a package.json in your root project directory and write below code in it and save.
      {
          "name": "grunt-demo",
          "version": "0.1.0",
          "devDependencies": {
              "grunt" : "~0.4.0",
              "grunt-contrib-uglify": "*",
              "grunt-contrib-watch": "*",
              "grunt-htmlhint": "*",
              "matchdep": "*"
          }
      }
    • Now run  npm install  to install Grunt and grunt plugins.
  5. Grunt setup needs: Gruntfile.js:
    • This file is named Gruntfile.js or Gruntfile.coffee and is used to configure or define tasks and load Grunt plugins.
    • It is comprised of the following parts:
      • The “wrapper” function.
      • Project and task configuration.
      • Loading Grunt plugins and tasks.
      • Custom tasks.
    • Below is just a sample code format for Gruntfile.js for understanding and it is not the actual file for our demo.
      // The "wrapper" function.
      module.exports = function(grunt){
          // Inside this all configuration are written like using the grunt plugins on files and doing runt tasks.
          grunt.initConfig({
              // All code related to grunt plugins configuration.
          });
          
          // Loading Grunt plugins and tasks.
          grunt.registerTask('default', []);
      };
  6. Setting up our demo files:
    • package.json: This file you must have already created from above post at point 4 and running ‘npm install’ to install all required packages/plugins for grunt.
    • Gruntfile.js: Below is the Gruntfile.js code which we will use for our demo and it uses below grunt plugins:
      • htmhint: To make sure HTML is written correctly that is validating HTML page with htmlhint.
      • uglify: To minify js file.
      • watch: To watch mentioned path/files for modifications and then apply htmlhint/uglify if files are changed or new files are created at a specified path.
        Create a Gruntfile.js in your root project directory and write below code in it and save.

        module.exports = function(grunt) {
            "use strict";
        
            // If matchdep is not used then need to use grunt.loadNpmTasks("grunt-task-name"); for each plugin/dependency.
           require("matchdep").filterDev("grunt-*").forEach(grunt.loadNpmTasks);
        
            grunt.initConfig({
                pkg: grunt.file.readJSON('package.json'),
                htmlhint: {
                    build: {
                        options: {
                            // Force tags to have a closing pair
                            'tag-pair': true,
                            // Force tags to be lowercase
                            'tagname-lowercase': true,
                            // Force attribute names to be lowercase e.g. <div id="header"> is invalid
                            'attr-lowercase': true,
                            // Force attributes to have double quotes rather than single
                            'attr-value-double-quotes': true,
                            // Force the DOCTYPE declaration to come first in the document
                            'doctype-first': true,
                            // Force special characters to be escaped
                            'spec-char-escape': true,
                            // Prevent using the same ID multiple times in a document
                            'id-unique': true,
                            // Prevent script tags being loaded in the  for performance reasons
                            'head-script-disabled': true,
                            // Prevent style tags. CSS should be loaded through 
                            'style-disabled': true
                        },
                        src: ['index.html']
                    }
                },
                uglify: {
                    build: {
                        files: {
                            'js/test.min.js': ['js/test.js']
                        }
                    }
                },
                watch: {
                    html: {
                        files: ['index.html'],
                        tasks: ['htmlhint']
                    },
                    js: {
                        files: ['js/test.js'],
                        tasks: ['uglify']
                    }
                },
        
            });
        
            grunt.registerTask('default', []);
        };
    • In the above file we are using index.html and test.js so let’s create these simple files.
    • index.html

      <!DOCTYPE html>
      <html lang="en">
          <head>
              <meta charset="utf-8">
              <meta name="viewport"   content="width=device-width; initial-scale=1.0; maximum-scale=1.0;">
              <title>Enter your first name</title>
              <link rel="stylesheet"  href="build/css/master.css">
          </head>
          <body>
              <label for="firstname">Enter your first name</label>
              <input id="firstname" name="firstname" type="text">
              <p id="namevalidation" class="validation"></p>
              <script type="text/javascript" src="build/js/base.min.js"></script>
          </body>
      </html>
    • js/test.js

      function test () {
          // Testing grunt demo
          console.log('testing grunt demo');
          alert('testing grunt demo');
      }
    • That’s all for our demo files so the structure of files should look like below:
  7. Using Grunt: (Run all below mentioned commands from command line from the root path of your project)
    • Using grunt to htmlhint our file: (Commands will check and show an error if there are any HTML code standard error present which we defined in htmlhint object in our Gruntfile.js)
      • Check htmlhint manually for a file having no error:
        Without modifying our index.php, run below command:
        grunt htmlhint
        Above will show no error as all rule specified in Gruntfile.js for htmlhint object are true and valid.
      • Check htmlhint manually for a file having error:
        Now change our index.html file to change any tag in uppercase. like change ‘title’  to ‘TITLE’, save the file and then run the same above command:
        grunt htmlhint
        Above will show error as we have specified in Gruntfile.js that our HTML file should have tags in lowercase. (‘attr-lowercase’: true)
      • Check htmhint automatically on file modification/creation:
        Run grunt watch from the command line which will show output as “Running ‘watch’ task. Waiting…”
        Now modify our HTML file to change any tag from uppercase to lowercase or vice versa to see an error in case of uppercase and no error while changing to lowercase.
    • Using grunt to uglify/minify our file:
      • Use uglify manually to minify our js file:
        Run grunt uglify and check that our test.js will be minified with new file test.min.js
      • Use uglify automatically to minify our js file:
        Run grunt watch from the command line which will show output as “Running ‘watch’ task. Waiting…”
        Now modify our js file to add any new code or remove code and save the file to see that test.min.js will be recreated with newly updated codes as it is being watched by grunt for any modification.
  8. So this is how you can start with Grunt.js and learn how to use it.
    There are many more Grunt plugins available which you can check at https://gruntjs.com/plugins and start using it in your project as per your need.

Reference:

3 thoughts on “Getting started with Grunt – The JavaScript Task Runner”

  1. Note on setting up package.json:
    1. Running ‘npm init’ can also create default package.json file for you to use.
    2. and then individual plugins can be installed using below command where giving parameter as ‘–save-dev’ will automatically add these to the list of dependencies in the package.json as well.
    sudo npm install grunt –save-dev
    sudo npm install grunt-htmlhint –save-dev
    sudo npm install grunt-contrib-watch –save-dev
    sudo npm install grunt-contrib-uglify –save-dev
    sudo npm install matchdep –save-dev

    Instead of running install command file for individual plugins, you can write on command for all plugins as comma separate like:
    sudo npm install grunt grunt-contrib-uglify grunt-contrib-watch grunt-htmlhint matchdep –save-dev

    So this way using above process as well you can create and update your package.json file from npm command instead of creating the file and adding code manually.

Leave a Reply

Your email address will not be published.

13 Shares
Tweet
Pin
Share4
Share9
Share
%d bloggers like this: