In this article, we’ll see how we can boost our Grunt build configuration to get the most out of it. From a developer perspective, this basically means to ease and improve the development with Grunt.

Load multiple Grunt tasks at once

If you’re somehow familiar with Grunt you may know that, usually, tasks need to be loaded one by one, which is pretty cumbersome.

The plugin load-grunt-tasks will read the dependencies / devDependencies / peerDependencies / optionalDependencies in the package.json and load Grunt tasks that match the provided patterns.

Usage

// Gruntfile.js
module.exports = (grunt) => {
  require('load-grunt-tasks')(grunt);
}

The above code loads all Grunt tasks, as

require('load-grunt-tasks')(grunt);

is equivalent to

loadTasks(grunt, {pattern: ['grunt-*', '@*/grunt-*']});

See more examples here.

Splitting your Grunt configuration

load-grunt-config is a Grunt library that allows you to break up your Gruntfile config by tasks. For most small projects a single Gruntfile.js is perfect. But as a project grows, the Gruntfile.js can quickly become unmanageable; this is where load-grunt-config comes in handy.

This library has lots of features (as you can see on the plugin documentation), but one of the most interesting ones are the aliases.

Usage

// Gruntfile.js
module.exports = (grunt) => {
  require('time-grunt')(grunt);
}

Aliases

To define custom tasks, you must create an aliases.(js|.json|yaml|cson|coffee) file in your grunt/ folder, load-grunt-config will use it to define your tasks aliases (like grunt.registerTask('default', ['jshint']);).

Example YAML file grunt/aliases.yaml

default: []

lint:
  description: 'Helps to make our code better'
  tasks:
    - 'jshint'
    - 'csslint'

build:
  - 'lint'
  - 'mocha'
  - 'notify'

In this example, if you run grunt lint in your terminal, jshint and csslint tasks will be executed. Likewise, if you execute grunt build, lint, mocha and notify tasks will be executed. Very simple.

Measure execution time

time-grunt displays the elapsed execution time of Grunt tasks, which gives useful information on how each task is performing.

time-grunt screenshot

time-grunt screenshot

Usage

// Gruntfile.js
module.exports = (grunt) => {
  require('time-grunt')(grunt);
}

Optional callback

If you want to collect the timing stats for your own use, pass in a callback:

time(grunt, (stats, done) => {
    // do whatever you want with the stats 
    uploadReport(stats);
 
    // be sure to let grunt know when to exit 
    done();
});

Clean layout

The watch task and tasks that take less than 1% of the total time are hidden to reduce clutter.

Run grunt with grunt –verbose to see all tasks.

Run multiple tasks in parallel

grunt-concurrent allows running multiple tasks at once. Running slow tasks concurrently can potentially improve your build time significantly. This task is also useful if you need to run multiple blocking tasks at once.

This addon is loaded using load-grunt-tasks. To configure this addon you just need to create a new file grunt/concurrent.js:

module.exports = {
  first: ['task1'],
  second: ['heavy1', 'heavy2']
};

In this example, we just set up to parallel execution tracks with the names first and second.

The task1 task needs to run first, and there’s nothing else to run in the meantime in our example. In our second track, we put both heavy1 and heavy2, since these two are independent of each other, and both take a considerable amount of time.

This on its own does not do anything yet. We have to change our default task alias to point to the concurrent jobs instead of the direct ones. Here’s the new content of grunt/aliases.yaml:

default:
  - 'concurrent:first'
  - 'concurrent:second'

If you now run your grunt build, the concurrent addon will run the task1 task first, and then spawn two threads on two different CPU cores to run both heavy1 and heavy2 in parallel.

JavaScript linter

grunt-eslint validates JavaScript files with ESLint.

Usage

You can use it like

// Gruntfile.js
module.exports = (grunt) => {
  require('grunt-eslint')(grunt);
}

To define where the validation must be run, you must create an eslint.js file in your grunt/ folder.

Example js file grunt/aliases.yaml

module.exports = {
  target: [
    'reporter/**/*.js',
    'test/**/*.js']
};

In this example, validation will be made on all js files under reporter and any sub-folder, as well as on all js files under test and any sub-folder.

Documentation generator

grunt-jsdoc is an addon to generate JavaScript documentation by running jsdoc3 in your Grunt project. It enables you to integrate the generation of comments-based documentation into your Grunt build.

Configuration

First, create the file grunt/jsdoc.js:

module.exports = {
  dist: {
    src: [
      'reporter/**/*.js',
      'task/**/.js',
      'csvreader/**/*.js',
      'index.js',
      'README.md'],
    options: {
      destination: 'reports/jsdocs',
      template: 'node_modules/ink-docstrap/template',
      configure: 'grunt/jsdoc/conf.json'
    }
  }
};

Supported options are:

  • src: an array of patterns that match the files to extract the documentation from. You can also include a README.
  • dest: (alias to options.destination) set up the destination folder, the grunt way
  • jsdoc: (optional) the path to the jsdoc bin (needed only for some border line cases)
  • options: options used by jsdoc
    • destination: the folder where the doc is generated
    • … All jsdoc options are available (see usejsdocCli documentation).
    • ignoreWarnings : (optional) do not show jsdoc warnings

 

I hope that you find the article informative, if you have any questions please don’t hesitate to ask.