SHARE
Facebook X Pinterest WhatsApp

Using JavaScript Task Runners

Written By
thumbnail
Rob Gravelle
Rob Gravelle
Apr 10, 2017

New Technology Based on an Old Idea

Back when I was in school during the early days of Windows, I learned about a neat application feature called a macro. They allow(ed) you to automate a number of operations so that you could execute at the click of a button. For example, I wrote one for MS Outlook that sends my articles to my editor. It took some time to set up, but now it saves me several minutes every time I email an article. So what happens when you need to combine several applications? In my school days there was something called the Component Object Model (COM), which allowed an application to interact with another via code. Outside of specific applications, there was DOS batch files, shell or bash scripts, and later, PowerShell.

Released in May of 2009, Node.js was a JavaScript runtime-environment capable of operating independently from the browser. This was a crucial milestone for JavaScript as Node.js was the catalyst that made it possible to create processing tasks for front-end JavaScript that were previously impossible. Several different tasks runners were developed shortly thereafter. The first of these, Jake, was created in 2010. Jake was soon followed by Grunt, Brunch, Mimosa, Gulp, Broccoli, and Yarn, to name but a few.

Grunt is considered to be the first “second generation” task runner to arrive on the scene. It’s relative longevity has provided ample time to amass a large database of plugins. However, Gulp has grown to become the most popular and widely supported system at the present time. Despite having been developed in parallel with Gulp, the third place Task Runner, Broccoli, has failed to keep up. The smaller number of tasks available to Broccoli may be a contributing factor.

Setting up Your Project

While each Task Runner differs both in terms of philosophy and in its method of writing tasks, there are some similarities. For instance, a typical Task Runner setup will involve adding two files to your project: package.json and the task file.

  1. package.json: This file is used by the Task Runner to store metadata for projects published as npm modules. You will list plugins your project needs as Dependencies and “devDependencies” in this file.
  2. task file: This is a .js or .coffee file that is used to configure or define tasks and load plugins.

Here’s are some simple package.json files for Grunt, Gulp, and Broccoli, respectively:

//Grunt
{
  "name": "My Grunt Project",
  "version": "0.1.0",
  }, 
  "scripts": { 
    "test": "grunt qunit" 
  }, 
  "devDependencies": {
    "grunt": "~0.4.5",
    "grunt-contrib-jshint": "~0.10.0",
    "grunt-contrib-nodeunit": "~0.4.1",
    "grunt-contrib-uglify": "~0.5.0"
  }
}

//Gulp
{ 
     "name": "My Gulp Project", 
     "version": "0.0.1", 
     "private": true, 
     "scripts": { 
         "start": "node app" 
     }, 
     "dependencies": { 
         "express": "3.1.0", 
         "jade": "*" 
     }, 
     "devDependencies": { 
         "gulp": "*", 
         "gulp-coffee": "*", 
         "gulp-rename": "*", 
         "gulp-less": "*", 
         "gulp-uglify": "*", 
         "gulp-clean": "*", 
         "gulp-csso": "*" 
     } 
} 

//Broccoli
{ 
   "name": "My Broccoli Project", 
   "version": "0.0.0", 
   "description": "", 
   "main": "Brocfile.js", 
   "scripts": { 
   "test": "echo "Error: no test specified" && exit 1" 
  }, 
   "author": "", 
   "license": "ISC", 
   "devDependencies": { 
     "broccoli": "^0.13.3", 
     "broccoli-6to5-transpiler": "^3.0.0", 
     "broccoli-coffee": "^0.4.0", 
     "broccoli-concat": "0.0.12", 
     "broccoli-merge-trees": "^0.2.1", 
     "broccoli-sass": "^0.3.3", 
     "broccoli-traceur": "^0.12.0", 
     "gulp": "^3.8.11", 
     "gulp-coffee": "^2.3.1", 
     "gulp-concat": "^2.4.3", 
     "gulp-ruby-sass": "^1.0.0-alpha.3", 
     "lodash-node": "^3.2.0" 
   } 
} 

devDependencies vs. Dependencies

In the three package.json files above, you can see some dependencies and something called “devDependencies.” To clarify the difference between the two, dependencies are resources that are required to run, whereas devDependencies are only required to develop, e.g.: unit tests, CoffeeScript to JavaScript transpilation, minification, etc… The devDependencies object is for those resources that another developer probably wouldn’t want or need. For instance, if someone was planning on downloading and using your module in their program, then they likely wouldn’t want to download and build the external test or documentation framework that you use.

Configuring Tasks

Tasks are defined in a special .js or .coffee file. It’s usually named according to the system, i.e.: Gruntfile.js, gulpfile.js, and Brocfile.js respectively.

// Gruntfile.js
module.exports = function(grunt) {
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-uglify');

  grunt.initConfig({
    concat: {
      scripts: {
        src: ['src/**/*.js'],
        dest: 'temp/all.js'
      }
    },
    uglify: {
      scripts: {
        src: 'temp/all.js',
        dest: 'build/all.js'
      }
    },
  });

  grunt.registerTask('default', ['concat:scripts', 'uglify:scripts']);
};

// gulpfile.js
var gulp   = require('gulp');
var uglify = require('gulp-uglify');
var concat = require('gulp-concat');

gulp.task('default', function() {
  return gulp
         .src('src/**/*.js')
         .pipe(concat('all.js'))
         .pipe(uglify())
         .pipe(gulp.dest('build/'));
});

//Brocfile.js
var babel  = require('broccoli-babel-transpiler')
var funnel = require('broccoli-funnel')
var concat = require('broccoli-concat')

var appJs = babel('src')

// Concatenate all the JS files into a single file
appJs = concat(appJs, {
  inputFiles: ['*.js'],
  outputFile: 'index.js'
})

module.exports = appJs

Conclusion

Now that we’ve covered what goes into adding a Task Runner to your Web project, we’ll move into specifics of how to work with individual Task Runners.

Recommended for you...

The Revolutionary ES6 Rest and Spread Operators
Rob Gravelle
Aug 23, 2022
Ahead of Time (AOT) Compilation in Angular
Tariq Siddiqui
Aug 16, 2022
Converting a JavaScript Object to a String
Rob Gravelle
Aug 14, 2022
Understanding Primitive Type Coercion in JavaScript
Rob Gravelle
Jul 28, 2022
HTML Goodies Logo

The original home of HTML tutorials. HTMLGoodies is a website dedicated to publishing tutorials that cover every aspect of being a web developer. We cover programming and web development tutorials on languages and technologies such as HTML, JavaScript, and CSS. In addition, our articles cover web frameworks like Angular and React.JS, as well as popular Content Management Systems (CMS) that include WordPress, Drupal, and Joomla. Website development platforms like Shopify, Squarespace, and Wix are also featured. Topics related to solid web design and Internet Marketing also find a home on HTMLGoodies, as we discuss UX/UI Design, Search Engine Optimization (SEO), and web dev best practices.

Property of TechnologyAdvice. © 2025 TechnologyAdvice. All Rights Reserved

Advertiser Disclosure: Some of the products that appear on this site are from companies from which TechnologyAdvice receives compensation. This compensation may impact how and where products appear on this site including, for example, the order in which they appear. TechnologyAdvice does not include all companies or all types of products available in the marketplace.