Building the Project with Grunt

Before we dive into our project’s code, we need to solve a problem: browsers don’t understand CoffeeScript. And they don’t understand Eco, the templating language you’ll meet a bit later. They only understand JavaScript. So how do we turn our source files into JavaScript with minimal pain and frustration?

The answer is Grunt.[38] Grunt is a Node.js-based task runner, well-suited to compiling our project assets (Eco templates and CoffeeScript modules) into JavaScript. In fact, it already has plugins that tell it how to do those exact things!

Let’s start by setting up our project directory:

 $ ​​mkdir​​ ​​coffee-tasks
 $ ​​cd​​ ​​coffee-tasks
 $ ​​npm​​ ​​init

npm will give you a series of prompts, which will fill in the project’s initial package.json. Now we can use npm to install Grunt and the plugins we need, while saving those dependencies to package.json in case we need to reinstall them later:

 $ ​​npm​​ ​​install​​ ​​-g​​ ​​grunt-cli
 $ ​​npm​​ ​​install​​ ​​--save-dev​​ ​​grunt
 $ ​​npm​​ ​​install​​ ​​--save-dev​​ ​​grunt-eco
 $ ​​npm​​ ​​install​​ ​​--save-dev​​ ​​grunt-contrib-coffee
 $ ​​npm​​ ​​install​​ ​​--save-dev​​ ​​grunt-contrib-watch

Careful readers will notice that we just installed Grunt twice. Actually, this is a quirk of how Grunt works: to get a grunt command we can run directly, we need to install Grunt globally. Hence, -g for “global.” But wait—what if we had multiple projects on the same machine that required different versions of Grunt? The designers of Grunt came up with a clever solution for this all-too-common software headache: when you install Grunt globally, what you’re really installing is just a thin wrapper (called grunt-cli) that loads the grunt package from the local project. That way, every project can have its own Grunt, despite sharing the same grunt command!

Now we have all the npm packages we need for our Gruntfile. This is the file that Grunt looks for every time we run it. It tells Grunt which files it needs to compile and where to put the results of that compilation. Oh, and we can write it in CoffeeScript:

 module.exports = (grunt) ->
  grunt.loadNpmTasks(​'grunt-eco'​)
  grunt.loadNpmTasks(​'grunt-contrib-watch'​)
  grunt.loadNpmTasks(​'grunt-contrib-coffee'​)
 
  grunt.initConfig
  watch:
  coffee:
  files: ​'src/*.coffee'
  tasks: [​'coffee:compile'​]
  eco:
  files: ​'templates/*.eco'
  tasks: [​'eco:compile'​]
 
  coffee:
  compile:
  expand: true
  flatten: true
  options:
  sourceMap: true
  cwd: ​'src/'
  src: [​'*.coffee'​]
  dest: ​'compiled/'
  ext: ​'.js'
 
  eco:
  compile:
  src: ​'templates/*.eco'
  dest: ​'compiled/templates.js'
 
  grunt.registerTask(​'build'​, [​'coffee'​, ​'eco'​])
  grunt.registerTask(​'default'​, [​'build'​, ​'watch'​])

This file does three things:

  1. Compiles our CoffeeScript files from the src directory into the compiled directory. (Because we specified the sourceMap: true option, we’ll also get a js.map file alongside each compiled js file.)

  2. Compiles our Eco files from the templates directory into the compiled directory.

  3. Watches those CoffeeScript and Eco files and recompiles them whenever they change.

This is an ideal setup for local development, so I’ve made this the default task. That means that all we have to do to kick things off is:

 $ ​​grunt

Grunt is an enormously flexible tool. If we were preparing our project for production, we could also use Grunt to concatenate our JS, run tests, and perhaps even deploy our files to staging and production. For more information on Grunt, check out Automate with Grunt [Hog14] from The Pragmatic Bookshelf.

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

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