Grunt Cookbook - Leanpub - samples.leanpub.comsamples.leanpub.com/gruntcookbook-sample.pdf · Grunt...

17

Transcript of Grunt Cookbook - Leanpub - samples.leanpub.comsamples.leanpub.com/gruntcookbook-sample.pdf · Grunt...

Grunt CookbookEffective Recipes To Master Grunt

Matt Goldspink

This book is for sale at http://leanpub.com/gruntcookbook

This version was published on 2014-02-14

This is a Leanpub book. Leanpub empowers authors and publishers with the Lean Publishing process. LeanPublishing is the act of publishing an in-progress ebook using lightweight tools and many iterations to getreader feedback, pivot until you have the right book and build traction once you do.

©2013 - 2014 Matt Goldspink

Tweet This Book!Please help Matt Goldspink by spreading the word about this book on Twitter!

The suggested hashtag for this book is #gruntcookbook.

Find out what other people are saying about the book by clicking on this link to search for this hashtag onTwitter:

https://twitter.com/search?q=#gruntcookbook

Contents

Contact Me 1

Introduction 2

Installing node and grunt CLI 4

Validating your JavaScript for common errors 8

Using Grunt to enforce coding standards 11

Contact MeGrunt Cookbook is a work in progress. If you have any feedback about recipe’s you’d like to see, mistakes,improvements, or if you have any questions then please email me at [email protected].

Introduction• Do you ever find yourself repeating tasks over and over?• Do you feel like you’re losing time with slow and mundane tasks?• Are you skipping some tasks in your dev lifecycle because they’re too annoying and get in the way?

If you’re a frontend developer with these issues then Grunt is going to be right up your street.

I wrote this book after using Grunt in a large enterprise and a startup to replace aging and painfully slow Antbased build systems. I loved that all the plugins for JSHint, Compass, concat/minify and more were availablestraight away. As I started to use it more I realised that there was a lot more power and potential to Gruntthan just a build system. I wanted to share my own learnings and insights in the hope that some or all of therecipe’s in the book resonate with you and inspire you to automate more of you daily tasks.

I’d love to hear from you if you’ve any questions or feedback then please reach out to me on twitter@mattgoldspink.

What is Grunt?

Grunt describes itself as “The JavaScript Task Runner”. It is essentialy a utility to help automate tasks, forexample you could automate:

• Concatenating JavaScript files when the files are saved• Running validation and testing across a projects code base• Generating documentation• Compiling meta-languages (i.e. Coffeescript or SASS) and uploading the output to a remote server

In fact if there’s a set of common actions you perform in your daily routine, chances are it can be automatedwith grunt and you could use that time to spend on something of more value.

Who is this book for?

This book is aimed at new and existing users of Grunt who want a quick reference manual about manycommon tasks in Grunt, or who want to see what Grunt can do for them and see how Grunt can be used towrite tasks beyond the conventional development lifecycle examples.

To get the most out of this book you should be familiar with the JavaScript language and have some minimalexperience with Node.js and installing Node.js modules using the Node Package Manager npm. Some recipe’sare specific to certain frameworks/languages, in those cases it is assumed you have some base knowledge ofthat particular framework/language.

Introduction 3

Sample Projects

If you’re anything like me, you’ll want to see real working examples, demonstrating:

• The final Gruntfile.js for each recipe• Where the source files are on disk for the given configuration• Where the output will get written to• Any additional files that are sometimes just “obvious” to developers, but not to beginners

All the recipe’s in the book were written around these examples to make sure you don’t get some half-broken,outdated code. With the examples you’ll get to see the recipes in action with the right dependencies at thetime of writing.

In addition they are all git projects with numbered branches that show the recipe at different stages. Thismeans that you can follow the progress of a recipe as it builds up by checking out the different branches.Where ever you see a command line snippet with Project: git checkout then that is an indicator to changebranches. For example in the Running Jasmine Tests recipe you’ll see something like this.

Example of git branch change

In the root directory of that sample project just run:

$ git checkout 02

and it will switch you to the branch which holds the code for this stage of the project. The name of thedirectory of the sample project is listed at the end of each recipe.

Getting the sample projectsThe sample projects are only available if you purchase “The Book + Code Samples” package.

Installing node and grunt CLI

Problem

As any fine chef knows you gotta have the right tools for the job and our case the tools are Node.js and GruntCLI. Note that we’re not installing Grunt as that is installed on a per project basis, but we’re installing thecore dependencies that all Grunt based projects will need.

Ingredients

A terminal, or command prompt, and a web browser.

Solution

For all OS’s you’ll need to head over to http://nodejs.org/download/ and choose the appropriate platform

http://nodejs.org/download/

Mac

From the node.js download page choose the “Macintosh Installer”. This will download a .pkg file which youcan then run. Follow the steps of the installer through to completion.

Once the install is completed you’ll need to install the Grunt Command Line Interface, or Grunt CLI as it’sknown. Open up your favourite terminal and first type:

Installing node and grunt CLI 5

$ node -v

This should print the version of Node.js you installed. If you get an error then something is not right with theinstall, you should follow up on the Node.JS mailgroup or IRC chat forum for specific help with your error.

If all is good then we can continue, to get the Grunt CLI we need to use NPM, the package manager for Node.It’s likely you’ll want to install the Grunt CLI so it’s available for every project and that will likely need youto install as the root user globally, so run:

$ sudo npm install -g grunt-cli

This will prompt you for your password so the grunt-cli files can be shared between all users and projects onthe machine. When it’s complete you should be able to run:

$ grunt

grunt-cli: The grunt command line interface. (v0.1.9)

Fatal error: Unable to find local grunt.

If you're seeing this message, either a Gruntfile wasn't found or grunt

hasn't been installed locally to your project. For more information about

installing and configuring grunt, please see the Getting Started guide:

http://gruntjs.com/getting-started

Don’t worry that it says “Fatal error”, this occurs because we’re not in a project directory which is using grunt,but it’s a sign that Grunt CLI and node are working and you’re all set to start working with Grunt.

Where do I find a terminal on Mac?If you’re not familiar with terminals then you may want to read up a little first because gruntrequires a little bit of knowledge of some basic terminal commands. To open the Mac terminal,press cmd + space and type “terminal” and hit enter

Windows

From the node.js download page choose the “Windows Installer”. This will download a .msi file which youcan then run. Follow the steps of the installer through to completion.

Once the install is completed you’ll need to install the Grunt Command Line Interface, or Grunt CLI as it’sknown. Open up a command prompt and type:

Installing node and grunt CLI 6

> node -v

This should print the version of Node.js you installed. If you get an error then something is not right with theinstall, you should follow up on the Node.JS mailgroup or IRC chat forum for specific help with your error.

If all is good then we can continue, to get the Grunt CLI we need to use NPM, the package manager for Node.It’s likely you’ll want to install the Grunt CLI so it’s available for every project and that will need us to passin he “-g” flag, so run:

> npm install -g grunt-cli

When it’s complete you should be able to run:

> grunt

grunt-cli: The grunt command line interface. (v0.1.9)

Fatal error: Unable to find local grunt.

If you're seeing this message, either a Gruntfile wasn't found or grunt

hasn't been installed locally to your project. For more information about

installing and configuring grunt, please see the Getting Started guide:

http://gruntjs.com/getting-started

Don’t worry that it says “Fatal error”, this occurs because we’re not in a project directory which is using grunt,but it’s a sign that Grunt CLI and node are working and you’re all set to start working with Grunt.

Linux

Installing node.js on Linux can be done in various ways depending on your Linux distribution and packagemanager. In all cases it is best to follow the guidance on this page https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager.

Once the install is completed you’ll need to install the Grunt Command Line Interface, or Grunt CLI as it’sknown. Open up a shell and type:

> node -v

This should print the version of Node.js you installed. If you get an error then something is not right with theinstall, you should follow up on the Node.JS mailgroup or IRC chat forum for specific help with your error.

If all is good then we can continue, to get the Grunt CLI we need to use NPM, the package manager for Node.It’s likely you’ll want to install the Grunt CLI so it’s available for every project and that will likely need youto install as the root user globally, so run:

Installing node and grunt CLI 7

$ sudo npm install -g grunt-cli

When it’s complete you should be able to run:

$ grunt

grunt-cli: The grunt command line interface. (v0.1.9)

Fatal error: Unable to find local grunt.

If you're seeing this message, either a Gruntfile wasn't found or grunt

hasn't been installed locally to your project. For more information about

installing and configuring grunt, please see the Getting Started guide:

http://gruntjs.com/getting-started

Don’t worry that it says “Fatal error”, this occurs because we’re not in a project directory which is using grunt,but it’s a sign that Grunt CLI and node are working and you’re all set to start working with Grunt.

Post install steps

You should also run

$ npm uninstall -g grunt

This will remove any existing global installs of Grunt.

Why uninstall existing versions of grunt?When Grunt was first released it was recommended to be installed as a global, system widecommand. However this meant that projects wanting to use different versions of Grunt would notbe able to on the same system. In 0.4.0 the grunt-cli module was created which would invoke aproject local copy of Grunt when the grunt command was run. This means each project can specifythe exact version of Grunt it needs and not enforce that version on all other projects on the samemachine.

See also

• Node.js Downloads¹ - Node.js Download site• Grunt.js - Getting Started² - The official Grunt.js getting started guide

¹http://nodejs.org/download/²http://gruntjs.com/getting-started

Validating your JavaScript for common errors

Problem

JavaScript has garnered a reputation for being a language where it’s easy to lose control and shoot yourselfin the foot (sometimes only when in IE). As a part of the build it is a good idea to perform some staticanalysis to look for common coding errors that trip people up, e.g. trailing commas which break in IE, missingbraces which could cause unexpected flow issues, missing variable declarations which could lead to clobberingglobals.

Ingredients

Command Line:

$ npm install grunt-contrib-jshint --save-dev

In your Gruntfile.js

Gruntfile.js

3 grunt.loadNpmTasks("grunt-contrib-jshint");

Solution

JSHint is a static analysis tool that will parse your code and look for common errors based on a set of a rules,which you can turn on and off as you see fit.

Gruntfile.js

3 grunt.initConfig({

4 jshint: {

5 all: ["Gruntfile.js", "src/**/*.js", "tests/**/*.js"]

6 }

7 });

The above will run JSHint over the Gruntfile.js and all JavaScript files in our src and tests directories andvalidate them using JSHint’s default settings.

Validating your JavaScript for common errors 9

Project: git checkout 01

$ grunt jshint

Running "jshint:all" (jshint) task

>> 8 files lint free.

Done, without errors.

If you want to customise the rules you can set an options object

Gruntfile.js

3 grunt.initConfig({

4 jshint: {

5 options: {

6 curly: true,

7 eqeqeq: true,

8 eqnull: true,

9 browser: true,

10 globals: {

11 jQuery: true

12 }

13 },

14 all: ["Gruntfile.js", "src/**/*.js", "tests/**/*.js"]

15 }

16 });

Assuming your code has some errors you would typically see some output like:

Project: git checkout 02

$ grunt jshint

Running "jshint:all" (jshint) task

Linting src/js/app.js ...ERROR

[L18:C43] W033: Missing semicolon.

var todo = new Todo('todos-vanillajs')

Warning: Task "jshint:all" failed. Use --force to continue.

If you were to fix up the missing semicolon and re-run grunt you’d see

Validating your JavaScript for common errors 10

Project: git checkout 03

$ grunt

Running "jshint:all" (jshint) task

>> 2 files lint free.

Done, without errors.

Great! Our code is looking good.

See Also

• Sample project - validating_your_javascript_for_common_errors• JSHint options³ - A detailed list of all JSHint options that can be configured

³http://www.jshint.com/docs/#options

Using Grunt to enforce coding standards

Problem

On a shared code base with many developers it’s easy for people to bring their own personal preferencesfor tabs/spaces, comma first, single/double quotes, etc. Having a coding standard for these can help bringconsistency and comprehension to a project.

Ingredients

Command Line:

$ npm install grunt-contrib-jshint --save-dev

In your Gruntfile.js

Gruntfile.js

3 grunt.loadNpmTasks("grunt-contrib-jshint");

Solution

Aside from validating the code from errors, JSHint can also be used to check for and enforce stylistic issues.Let’s say we have a code standard with the following rules:

• Always uses double quotes for Strings• Always use 4 spaces for indentation• No comma first syntax• Variable names should be in camel case• Braces must be used for all blocks• All constructors must start with a Capital letter and be camel case• Our maximum line length is 120• There should be a maximum of 2 parameters per function

We could configure this like so:

Using Grunt to enforce coding standards 12

Gruntfile.js

3 grunt.initConfig({

4 jshint: {

5 options: {

6 quotmark: "double",

7 indent: 4,

8 laxcomma: false,

9 camelcase: true,

10 curly: true,

11 newcap: true,

12 maxlen: 120,

13 maxparams: 3

14 },

15 all: ["Gruntfile.js", "src/**/*.js", "tests/**/*.js"]

16 }

17 });

This will still run the validations from our previous recipe, but it will now also look for parts of the code whichbreak these rules and fail the build. There are more options available and of course you can tweak them tomeet your own coding standards.

Let’s see this in action on a sample project. Let’s assume we have an invalid app.js file which looks like:

src/js/app.js

1 /*global app */

2 (function () {

3 'use strict';

4

5 /**

6 * Sets up a brand new Todo list.

7 *

8 * @param {string} name The name of your new to do list.

9 */

10 function Todo(name) {

11 this.storage = new app.Store(name);

12 this.model = new app.Model(this.storage);

13 this.template = new app.Template();

14 this.view = new app.View(this.template);

15 this.controller = new app.Controller(this.model, this.view);

16 }

Running our grunt file with the JSHint config results in the following output:

Using Grunt to enforce coding standards 13

Project: git checkout 01

$ grunt jshint

Running "jshint:all" (jshint) task

Linting src/js/app.js ...ERROR

[L3:C17] W108: Strings must use doublequote.

'use strict';

[L11:C7] W015: Expected 'this' to have an indentation at 9 instead at 7.

this.storage = new app.Store(name);

[L12:C7] W015: Expected 'this' to have an indentation at 9 instead at 7.

this.model = new app.Model(this.storage);

Warning: Task "jshint:all" failed. Use --force to continue.

Aborted due to warnings.

Here we can see it’s found 3 issues:

1. We have a String which is using single quotes instead of double2. We have 2 errors related to incorrect indentation

Perfect!

If you’re in a team I’d recommend getting this task running in a continuous integration environment so thatas all developers check in their changes these checks don’t get skipped and that everyone is alerted whenproblems are discovered.

See Also

• Sample project - checking_your_developers_keep_your_code_format_standards• JSHint options⁴ - A detailed list of all JSHint options that can be configured• Maintainable Javascript by Nicholas Zakas⁵ - I highly recommend reading Nicholas’s book to get somesolid guidelines on setting up coding standards for JavaScript

⁴http://www.jshint.com/docs/#options⁵http://amzn.com/1449327680