Introducing Multitasks

Multitasks work by combining a task definition and a block of configuration that defines the targets. Unlike regular tasks, Grunt’s multitasks automatically look for a configuration section that matches the name of the task. So let’s create a simple configuration that explores how multitasks work.

We’ll use Node.js and the Open Weather API to grab the current temperature of some zip codes. We’ll configure the zip codes as targets and we’ll write a task to fetch the data for the temperatures.

First, create a new folder and a package.json file:

 
$ ​mkdir weather
 
$ ​cd weather
 
$ ​npm init

When prompted for values, use the defaults for everything.

Next, install Grunt as a dependency:

 
$ ​npm install grunt --save-dev

Then create a new Gruntfile like you’ve done in previous chapters:

multitasks/weather/Gruntfile.js
 
module.exports = ​function​(grunt){
 
}

Now, our plan is to use a multitask and some zip codes as targets. To do this, we define the configuration section using grunt.initConfig, and then we specify the targets and some associated zip code for each target:

multitasks/weather/Gruntfile.js
 
grunt.config.init({
 
weather: {
 
home: 60623,
 
work: 60622
 
}
 
});

Now we can declare our task:

multitasks/weather/Gruntfile.js
 
grunt.registerMultiTask(​'weather'​, ​'Fetches weather'​, ​function​() {
 
});

The task’s name has to match the configuration section for multitasks. When we run the task, it will automatically look for that configuration block.

Now we need to set up some variables. Inside a Grunt multitask we can access the target with this.target and we can access the data associated with that target with this.data.

multitasks/weather/Gruntfile.js
 
var​ done, http, location, request, requestOptions, zipCode;
 
 
location = this.target;
 
zipCode = this.data;

The location name is the target, and the zip code is the data.

To make the actual request, we’ll use Node’s built-in http module. This module provides a request method that takes an options object containing information about the type of request, the host, the port, and the path. We configure that like this:

multitasks/weather/Gruntfile.js
 
requestOptions = {
 
host: ​'api.openweathermap.org'​,
 
path: ​'/data/2.5/weather?units=imperial&q='​ + zipCode,
 
port: 80,
 
method: ​'GET'
 
}

All that’s left to do is make the request and parse the results. When we make the request, we’ll get the data back in chunks, which we’ll concatenate together. Then when we’ve gotten all the chunks, we’ll join them together, parse the response as JSON data, and display the temperature.

multitasks/weather/Gruntfile.js
Line 1 
http = require(​'http'​);
done = this.async();
request = http.request(requestOptions, ​function​(response) {
var​ buffer = [];
response.on(​'data'​, ​function​(data){
buffer.push(data);
10 
});
response.on(​'end'​, ​function​(){
var​ weather = JSON.parse(buffer.join());
console.log(location + ​' : '​ + weather.main.temp + ​' degrees'​);
15 
done();
});
});
20 
request.end();

Take a look at line 3. This line is incredibly important. Node’s http module is asynchronous, so when we make a request for the weather data, Node doesn’t wait for the response. Instead, it invokes the callback once the data gets back. Grunt, however, doesn’t wait around. It’ll finish the task run before we get our response.

Grunt has a workaround for this, though. We use this.async to tell Grunt that this task is asynchronous, and that it should wait until we tell it we’re done. So, on line 3 we create a variable called done by calling this.async. Then on line 16, once we’ve parsed the response, we invoke done as a function, which tells Grunt we’re all done. It’s kind of a strange pattern, but it works really well.

When we run this task, we get our weather report. This book was written in the middle of a very cold winter, so what you’re seeing are real Fahrenheit temperatures for the Chicago area:

 
$ ​grunt weather
 
Running "weather:home" (weather) task
 
home : 1.72 degrees
 
 
Running "weather:work" (weather) task
 
work : 1.85 degrees
 
 
Done, without errors.

If we added a new target and zip code, we’d get a third response. Multitasks make it very easy to configure a single task to handle multiple outputs.

Now let’s look at something a little more practical: file concatenation.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.216.34.146