Wrangling the JavaScript

Our index.html file is looking for a file called assets/app.js, but all we have are several separate CoffeeScript files. Using Grunt, we’ll compile those CoffeeScript files into a single JavaScript file, then combine that file with the Angular and Markdown libraries, creating a single file we can bring into our document. And to ensure that the file downloads even faster, we’ll minify it, which will remove whitespace and rename variables and functions to reduce the overall file size considerably.

Compiling CoffeeScript

Let’s set up a basic package.json and Gruntfile for our app. First, create package.json with the following contents:

 
{
 
"name": ​"MarkdownEditor"​,
 
"version": ​"0.0.1"​,
 
"description": ​"A simple markdown editing app"​,
 
"main": ​"index.html"​,
 
"author": ​"Max Power"​,
 
}

Next, create the Gruntfile.js file in the root of the application with the usual skeleton:

workflow/markdown/Gruntfile.js
 
module.exports = ​function​(grunt){
 
};

With those in place, we can install grunt and the grunt-contrib-coffee plug-in with npm:

 
$ ​npm install grunt --save-dev
 
$ ​npm install grunt-contrib-coffee --save-dev

And now we can configure the CoffeeScript plug-in to build the JavaScript files our browsers crave.

Chunked Configuration

So far we’ve used Grunt’s initConfig function to set up configuration variables. But we’re going to create a somewhat complex Gruntfile that might be hard to follow after awhile. Grunt offers a more modular way for us to define configurations with its config function. This lets us define our configuration in manageable pieces. Add this to the Gruntfile:

workflow/markdown/Gruntfile.js
 
grunt.loadNpmTasks(​'grunt-contrib-coffee'​);
 
grunt.config(​'coffee'​, {
 
app: {
 
options: {
 
bare: false
 
},
 
files: {
 
'tmp/compiled.js': [​'coffeescript/app.coffee'​,
 
'coffeescript/factories/*.coffee'​,
 
'coffeescript/controllers/*.coffee'​]
 
}
 
}
 
});

As you might be able to guess, the loadNpmModule loads a Grunt plug-in. Once we load the plug-in, we can configure it.

The CoffeeScript plug-in is designed as a multitask, so we’ll have to specify targets even though we’ll have only a single one. We’ll call our target app and then specify the files. The files key uses a simple JavaScript object, where we specify the destination file as the key, and then an array of source files as the value.

In some cases, you might be able to get away with just specifying coffeescript/**/*.coffee as the source, which would take all of the CoffeeScript files found within the coffeescript folder. But by being a little more specific, we can ensure that things are included in the right order.

In the Terminal, run the command grunt coffee, and you’ll see the output:

 
$ ​grunt coffee
 
Running "coffee:app" (coffee) task
 
 
Done, without errors.

Now, provided that we didn’t make any typos in our CoffeeScript files, we’ll see a new folder, called tmp in our project. It contains a new file called compiled.js that holds the compiled version of our CoffeeScript files. The separate files were stitched together into compiled.js. We’re not done with this file, though.

Concatenating JavaScript

The CoffeeScript compilation task put all of our application files into a single file when it converted them. But we’re going to bundle up the Angular libraries along with our own code to create a single JavaScript file.

We wrote our own simple task to do concatenation back in Chapter 3, One Task, Many Outputs, but this time we’ll use the grunt-contrib-concat plug-in instead, as it’s more flexible than what we wrote. To install it use npm as follows:

 
$ ​npm install grunt-contrib-concat --save-dev

Once the plug-in is installed, we require it in our configuration file and configure it the same way we did with the CoffeeScript plug-in.

workflow/markdown/Gruntfile.js
 
grunt.loadNpmTasks(​'grunt-contrib-concat'​);
 
grunt.config(​'concat'​, {
 
scripts: {
 
src: [​'bower_components/angular/angular.js'​,
 
'bower_components/angular-sanitize/angular-sanitize.js'​,
 
'bower_components/markdown/dist/markdown.js'​,
 
'tmp/compiled.js'​],
 
dest: ​'tmp/app.js'
 
}
 
});

We pull in the required libraries from the components folders, along with the file generated by our CoffeeScript code. We place the output back in the tmp folder because we’re not quite done with it yet.

Let’s run the task:

 
$ ​grunt concat
 
Running "concat:scripts" (concat) task
 
File "tmp/app.js" created.
 
 
Done, without errors.

We’re almost finished with the JavaScript side of things. However, the JavaScript file we just created is quite large. Let’s shrink it down.

Minifying JavaScript

To make our JavaScript download faster, we’re going to minify it. This process removes comments, whitespace, and line breaks, and even obfuscates code by shortening variable names. We’ll use the Uglify utility to do this by way of the grunt-contrib-uglify plug-in.

First, we install the plug-in:

 
$ ​npm install grunt-contrib-uglify --save-dev

By now you can probably guess how we’ll configure this. One of the nice things about Grunt plug-ins is they share a level of consistency. In the Gruntfile, load the plug-in and then add the configuration section, placing the output in the assets folder, which is where our index.html file looks for the JavaScript file.

workflow/markdown/Gruntfile.js
 
grunt.loadNpmTasks(​'grunt-contrib-uglify'​);
 
grunt.config(​'uglify'​, {
 
scripts: {
 
files: {
 
'assets/app.js' : ​'tmp/app.js'
 
}
 
}
 
});

And that takes care of the JavaScript! Test it out by running the following:

 
$ ​grunt uglify
 
Running "uglify:scripts" (uglify) task
 
File assets/app.js created: 816.58 kB → 128.81 kB
 
 
Done, without errors.

The task’s output shows us that by uglifying the content, we’ve turned more than 800 KB of JavaScript code into only 128 KB. That’s going to make the application download a lot faster, and illustrates why this minification process has become part of a modern workflow.

And that’s it for the JavaScript code.

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

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