Relax Breath of Solution.Community tech blog of Sameera Thilakasiri - Consultant UI, UX, RWD Specialist/ Interactive Designer

Just I wanted.. Do you?…

Nodejs & LessCSS and Grunt for your way to frontend development. Performance, optimization, and best practices.

Posted on April 2, 2014 | 4 Comments

Nodejs & LessCSS and Grunt for your way to frontend development. Performance, optimization, and best practices.

How does Nodejs & LessCSS and Grunt make easy the FED?

First off all LessCSS(Less is a CSS pre-processor, meaning that it extends the CSS language, adding features that allow variables, mixins, functions and many other techniques that allow you to make CSS that is more maintainable, themable and extendable.) changed the world of UI Engineering with its features. Less runs on both the server-side (with Node.js and Rhino) or client-side (modern browsers only). This is the place where NodeJS stands.

Node.js is a platform built on Chrome’s JavaScript runtime for easily building fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices.

The grunt, what is, the less work you have to do when performing repetitive tasks like minification, compilation, unit testing, linting, etc, the easier your job becomes. After you’ve configured it, a task runner can do most of that mundane work for you—and your team—with basically zero effort.

So in one word: automation, that the reason to use this combination.

For example, instead of minifying, image optimization, and concatenating CSS and JavaScript files manually, tools and processes are out there that can help and put these performance tasks into an automated workflow, and more importantly right from the beginning of a product development cycle.

Google’s “Make the Web Fast” team recommends frontend best practices

About Grunt

Using Grunt in Your Web Development Team

When used in a team environment, Grunt can help every person in that team write code that adheres to the same standards/style guides.
For example, when indenting code, you could automatically enforce the use of spaces instead of tabs (or vice versa, depending on your preferences), which will ensure that the whole team has the same configuration. When they push code to the repository, it’s in the expected format.
Used in conjunction with your favourite code-quality tools (for example, JSHint), Grunt will help you catch sloppy code such as missing semicolons, brakeless control statements, unused variables, and trailing whitespace. This is excellent for discovering human errors as well as disallowing valid, but badly written, JavaScript.

A few more examples of common Grunt tasks are:

  • Optimizing your web images
  • Concatenating JavaScript/CSS files into one file and minified for faster web page load times
  • Running scripts that analyse your code for potential errors (often referred to as linting)
  • Enforcing your coding style guides for uniformity and readability throughout your project’s code base
  • Compiling your CSS from LESS/Sass

How to install LessCSS?

Point to http://nodejs.org/download/ and download your preferred version. (I downloaded Win32 MSI, if you need help installing Node.js, read the following tutorial: How to Install Node.js (howtonode.org))

Install Grunt

Next, you need to install Grunt and its dependencies. We will install Grunt using Node.js’s npm.

Learn how to install Grunt with npm by reading this tutorial: Installing Grunt (gruntjs.com)

Steps to installation
1. Create a folder where you want to host and run Less

2. Open folder and point CMD to the folder (open the folder, press  and hold down the Shift key, then right click, on your context menu you should see the link “Open command window here”)

3. Command following (npm- Node Packaged Modules)

npm install  -g grunt

Let it to complete the task,

4. Again command (-g Make sure you install grunt-cli globally, the Grunt command line interface)

npm install -gq grunt-cli

Let it to complete the task,

5. Then command to

npm init 

(Interactively create a package.json file, this asks your number of questions but those are straight forward, if you want to know about more, its described here. https://www.npmjs.org/doc/files/package.json.html)

When you end this, check on the folder (Here after I called this location as root), followings can be seen.
package.json, node_modules folder

package.json

package.json is a JSON file. This file should be located in your project’s root directory.

Project information and settings are specified in package.json, such as the project name, version, author, and if it’s a private project or not.

package.json also contains what are known in the Node.js nomenclature as devDependencies. devDependencies are items you need for your project. In this sense, Grunt will be an item listed under devDependencies, along with the Grunt plugins you want to use for the project.

6. Then open the package.json and edit as follows

{
	"name": "lesshost",
	"version": "0.0.1",
	"description": " A packaged foo fooer for fooing foos",
	"main": "index.js",
	"scripts": {
		"test": "echo \"Error: no test specified\" && exit 1"
	},
	"author": " authorName",
	"license": "ISC",
	"devDependencies": {
		"grunt": "~0.4.1",
		"grunt-contrib-less": "~0.5.0",
		"grunt-contrib-watch": "~0.4.0"
	}
}

Save this and again run CMD on root
7. Command to

npm install

Once it completed gruntfile.js file is created on the root

Gruntfile

The Gruntfile is the main configuration file for the project, and specifies what tasks Grunt should run and what files in the project they affect.

Your project’s Gruntfile can be a JavaScript file (Gruntfile.js)

8. Create your first .less file on the root.

Ex:

/* Mixin */
.border-radius (@radius: 5px) {
   -webkit-border-radius: @radius;
   -moz-border-radius: @radius;
   border-radius: @radius;
}

/* Implementation */
#somediv {
   .border-radius(20px);
}

9. Open your gruntfile.js and update your css file name and path

// target.css file: source.less file
"./new.css": "./style.less",

I created the style.less file on root and expected new.css file from grunt

10. Command on root to

grunt

Check on the root. New.css file is created and following output can be seen.

/* Compiled CSS */
#somediv { -webkit-border-radius: 20px;  -moz-border-radius: 20px;  border-radius: 20px; }

11. But sure, your css has been minified. Make beautifier (format the css code) open the gruntfile.js and edit as follows

compress: false,
yuicompress: false,

Then to stop the CMD to watching. (Ctrl + C)

12. Again command to grunt. Check the new.css file should be beautified as follows

#somediv {
   -webkit-border-radius: 20px;
   -moz-border-radius: 20px;
   border-radius: 20px;
}

Done!!!

Using Grunt Plugins

A key feature of Grunt is the use of Grunt plugins. Grunt plugins are referred to as gruntplugins in the Grunt nomenclature.

Grunt plugins are user-contributed modules that will help you automate tasks without having to write your own task scripts.

How to install csslint for css validation?

What is CSS Lint?

CSS Lint is an open source CSS code quality tool originally written by Nicholas C. Zakas and Nicole Sullivan. It was released in June 2011 at the Velocity conference.

A lint tool performs static analysis of source code and flags patterns that might be errors or otherwise cause problems for the developer.

CSS Lint points out problems with your CSS code. It does basic syntax checking as well as applying a set of rules to the code that look for problematic patterns or signs of inefficiency.

Install csslint on Grunt

On your root open the CMD and command to

npm install grunt-contrib-csslint --save-dev

After the completing plugin installation, open gruntfile.js and amend following

csslint: {
	strict: {
		src: [*.css']
	},
	lax: {
		options: {
			csslintrc: '.csslintrc'
		},
		src: [*.css']
	}
}

End of the file add loadNpmTasks and registerTask as follows

grunt.loadNpmTasks('grunt-contrib-csslint');
grunt.registerTask('default', ['csslint:lax']);

TIP: Place registerTask before the grunt.registerTask(‘default’, [‘watch’]);
Then go to the root and create a file called .csslintrc where you can specify options for validation.
Let’s validate our css code.
Open the CMD and command to

grunt csslint:strict

on the CMD your warnings and errors will be shown clearly.

How to install jshint for js validation?

What is CSS Lint?

JSHint is a community-driven tool to detect errors and potential problems in JavaScript code and to enforce your coding conventions. It is very flexible so you can easily adjust it to your particular coding guidelines and the environment you expect your code to execute in.

Install jsHint on Grunt

On your root open the CMD and command

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

Once the plugin has been installed, it may be enabled inside your Gruntfile with these lines of JavaScript:

grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.registerTask('default', 'jshint');

Done!!!

Let’s validate your JS

Command to

grunt jshint 

Wow!!! Everything will be shown on CMD

How to install htmlhint for HTML validation?

I just have stated main steps, so hope you familiar with the steps. Hereafter let me brief,

Command to

npm install grunt-htmlhint --save-dev

One the plugin has been installed, it may be enabled inside your Gruntfile with this line of JavaScript:

grunt.loadNpmTasks('grunt-htmlhint');
grunt.registerTask('htmlhint');

Define rules(rules can be found here: https://github.com/yaniswang/HTMLHint/wiki/Rules) for validation; you can maintain a config file for this. (create .htmlhintrc file on root)
If this file name is specified, options and globals defined therein will be used. Task and target options override the options within the htmlhintrc file. The htmlhintrc file must be valid JSON and looks something like this:

{
  "tag-pair": true,
}

Then amend gruntfile.js with following:
Config file

htmlhint: {
  options: {
    htmlhintrc: '.htmlhintrc'
  },
  html1: {
    src: ['path/to/**/*.html']
  },
  html2: {
    src: ['path/to/**/*.html']
  }
}

How to concatenate JavaScript files into one file?

Install js concat for js file merge
Command to

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

Once plugin installed, amend the gruntfile.js

  concat: {
    options: {
      separator: ';',
    },
    dist: {
      src: ['src/intro.js', 'src/project.js', 'src/outro.js'],
      dest: 'dist/built.js',
    },
  }

Yaa, then need to update load and register

grunt.loadNpmTasks('grunt-contrib-concat');
grunt.registerTask('default', 'concat');

Done, let’s try it now.
Command to

grunt concat:dist

How to concatenate CSS files into one?

Install CSS concat for CSS file merge
Command to

npm install grunt-concat-css

Amend the gruntfile.js

  concat_css: {
    options: {
      // Task-specific options go here.
    },
    all: {
      src: ["*.css"],
      dest: "styles.css"
    },
  }

Update load and register

grunt.loadNpmTasks('grunt-concat-css');
grunt.registerTask('default', 'concat_css');

Command to

grunt concat-css

Style.css is created on the root.
Done.

How to minify CSS file using grunt?

Command to

npm install grunt-contrib-cssmin --save-dev

Amend the gruntfile to

cssmin: {
  combine: {
    files: {
      'path/to/output.css': ['path/to/input_one.css', 'path/to/input_two.css']
    }
  }
}

update load and register

grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.registerTask('default', ‘cssmin');

Command to

grunt cssmin

,
wow!!! Output file will be updated.

How to minify JS file using grunt?

Command to

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

Amend the gruntfile.js to

uglify: {
    my_target: {
      files: {
        'dest/output.min.js': ['src/input1.js', 'src/input2.js']
      }
    }
}

update load and register

grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.registerTask('default', ‘uglify');

Command to

grunt uglify

,
wow!!! Output file will be updated.

Finally! Let’s optimized our images.

How to optimize images (PNG,JPG,GIF) using grunt?

Command to

npm install grunt-contrib-imagemin --save-dev

Amend the gruntfile.js

  imagemin: {
    dynamic: {
      files: [{
        expand: true,
        cwd: 'assets/',
        src: ['**/*.{png,jpg,gif}'],
        dest: 'dist/'
      }]
    }
  }

update load and register

grunt.loadNpmTasks('grunt-contrib-imagemin');
grunt.registerTask('default', ‘imagemin');

Find the options available in optimization: https://github.com/gruntjs/grunt-contrib-imagemin

How to remove unused CSS?

Uncss is extremely useful if you are using a large front-end framework like Foundation or Bootstrap because most of the time you will only be using around 10% of the css.
The only problem when you ran into was that uncss would ignore JavaScript generated css. However, you can add an ignore option so that it doesn’t get rid of selected selectors.

uncss: {
	dist: {
		files: {
			'dist/css/app.css': ['app/index.html']
		}
	},
	options: {
		ignore: ['.js_classname']
	}
}

You can introduce a convention on your code base when you use JS based classes
Ex:

.js_classname

How to install Uncss (unused css remover) using grunt?

npm install grunt-uncss --save-dev

Once the plugin has been installed, it may be enabled inside your Gruntfile with this line of JavaScript:

grunt.loadNpmTasks('grunt-uncss');
grunt.registerTask('default', ‘uncss');
/
Run this task with the grunt uncss

command.
Along-side, specify the input HTML files you would like scanned for used selectors. In this case app/index.htmland app/about.html are the two files we would like checked.

uncss: {
  dist: {
    files: {
      'dist/css/tidy.css': ['app/index.html', 'app/about.html']
    }
  }
}

Which you can then use alongside a processor like processhtml to rewrite the location of your stylesheet totidy.css using a block like:

<!-- build:css css/tidy.css -->
<link rel="stylesheet" href="css/normalize.css">
<link rel="stylesheet" href="css/main.css">
<link rel="stylesheet" href="css/bootstrap.css">
<!-- /build -->

and some configuration like:

processhtml: {
  dist: {
    files: {
      'dist/index.html': ['app/index.html'],
      'dist/about.html': ['app/about.html']
    }
  }
}

Options and additional informations can be found here: https://www.npmjs.org/package/grunt-uncss

This is very helpful to minimize time and maximize the performance. Hope you will be enjoy the article and your ideas welcome.

Summary

In this tutorial, this is what we covered:
What Grunt is, and how it can help web developers speed up their workflow.
Installation of Node.js
Installation of Grunt
Installation of Grunt’s CLI
General usage of Grunt in web development projects
How to use a gruntplugin

Grunt file related to this article can be available at this git hub repo

Thank you Sameera Lokuliyana, given support during this work.

Resources:
http://sixrevisions.com/javascript/grunt-tutorial-01/

“Grunt” your way to frontend performance optimization


Author
Sameera Thilakasiri By Sameera Thilakasiri
,is a front-end developer based in Colombo, is a blogger and a lifestyle photographer.
Follow him Twitter and Google+. Check out him.

Comments

4 Responses to “Nodejs & LessCSS and Grunt for your way to frontend development. Performance, optimization, and best practices.”

  1. Isuru Asanka
    April 2nd, 2014 @ 6:37 am

    Thanks, this really cleared things up for me. Much easier to follow and includes key info missing from the official instructions. I’m up and running thanks to you.

  2. Iranga Udawatta
    April 2nd, 2014 @ 9:45 am

    Hello! Thank you for you text! I am publisher of a brazilian technology blog. Do you mind if I translate and publish your article, giving you all the credits and putting the original source link at the end? Best regards!

  3. Jon Thomas
    April 2nd, 2014 @ 2:48 pm

    I love its code validation and testing increases overall quality and helps you maintain a constant coding standard, which makes Grunt also a perfect tool for teams working on large scale projects.

  4. Brian Lamb
    April 2nd, 2014 @ 7:21 pm

    Thanks a lot.. i’d no much time to understand what grunt is. You learnt it well to me. Best regards from Paris

Leave a Reply

You must be logged in to post a comment.