Automate your workflow with Grunt

Alex R Chies
Across the mirror
Published in
5 min readMay 12, 2015

Maybe any of you have tried Ant, Maven or any software similar. At the beginning, they seems hard to configure and difficult to use but it’s not when you understand the idea and saves huge amounts of time you can use in more productive things than repetitive ones.

Certainly, the first time you install it following a tutorial or the official documentation you think it’s probably like the hell but I can ensure that you can learn, run, configure and understand a Grunt in few hours (2–3 at maximum).

At first, surely you won’t save enough tasks to think worthwhile the efforts but, the more you use the more you discover features and plugins and you begin to be excited about the possibilities.

Trust me, for an inversion of few hours, Grunt will save you a lot of ones more and will improve drastically the quality of your work and the knowledge of the last tools using them simply as plugins.

Why Grunt improve the QA of my work

Grunt puts in your hand the power of the most complete collection of plugins for the most modern tools, frameworks and much more so you can install and begin to use new techniques, tests and optimizations in the easiest way.

Introduce them into your workflow is a question of 2 minutes and save you a lot of headaches, centralizing the whole tools your project uses in an unique file.

Are you convinced to give it a chance? Here we go!

Installing Node.js

The first thing we need is install Node.js that is the language Grunt was built.

There are installers for Mac and Windows so It’s not a problem.

One your Node.js is installed you can begin use the npm (Node Package Manager).

Installing Grunt

To use Grunt, we need install the CLI (Command Line Interface) using npm.

For that, we open a console with administrator rights using sudo for OSX or nix or running the shell in Windows as administrators. Then, we run this:

npm install -g grunt-cli

This lets us run Grunt anywhere in the system path but, beware!, this is not the Grunt installation for our project. This is the installation for the CLI that we must only do one time.

Run Grunt in a project

To begin use Grunt in our project, we need create two files: package.json and Gruntfile.js. The first file will be created when we add Grunt plugins to our environment. The second must be created manually by us.

So, It’s the time to decide what plugins we want for our project. It could be modified in the future, adding or deleting some plugins we want. In the page gruntjs.com/plugins we can see the whole plugin collection. To install one, we must run this from the shell (in the project root path):

npm install <module-name> --save-dev

This installs the module in the folder /node_modules/ and the — save-dev param adds the version of the module to our package.json file.

We can add some information we want to the package.json file about the author or version of our project. Below, we can see an example of a package.json file that I use for a real project. You can see the plugins installed and the version they need:

{ "name": "my project", "version": "0.1.0", "engines": { "node": ">= 0.10.0" }, "devDependencies": { "grunt": "~0.4.2", "grunt-contrib-watch": "~0.5.3", "grunt-contrib-cssmin": "~0.7.0", "grunt-contrib-csslint": "~0.2.0", "grunt-contrib-sass": "~0.7.2", "grunt-contrib-copy": "~0.5.0" } }

Well, with our package.json file ready, we need to create our Gruntfile.js file. The Gruntfile is the file where we say Grunt what we want it does and how.

In the gruntjs.com/plugins webpage, we can see the syntax to configure the different plugins in the Gruntfile.

Continuing the above example, you can see an example of my Gruntfile:

module.exports = function(grunt) { // Project configuration. grunt.initConfig({ // Metadata. pkg: grunt.file.readJSON('package.json'), // Task configuration. watch: { sass: { files: ['sass/*.scss', 'sass/components/*.scss'], tasks: ['sass', 'csslint', 'cssmin'], options: { livereload: 51336 } }, css: { files: ['sass/_output/*'], tasks: ['csslint', 'cssmin'], options: { livereload: 51337 } }, html: { files: ['../page/**/*'], tasks: ['copy'], options: { livereload: 51338 } }, assets: { files: ['../design/assets/**/*'], tasks: ['copy'], options: { livereload: 51339 } } }, sass: { dist: { files: [ {'sass/output/index.css': 'sass/index.scss'} ] } }, csslint: { strict: { options: { import: 2 }, src: ['sass/output/index.css'] }, lax: { options: { import: false }, src: ['sass/output/index.css'] } }, cssmin: { combine: { files: { '../page/css/styles.css': ['sass/output/*.css'] } } }, copy: { main: { files: [ {expand: true, cwd: '../design/', src: ['assets/**/*', '!assets/**/*.db'], dest: '../page/'}, {expand: true, src: ['../page/**', '!../page/**/*.db'], dest: '//production/'} ] } } }); // These plugins provide necessary tasks. grunt.loadNpmTasks('grunt-contrib-watch'); grunt.loadNpmTasks('grunt-contrib-sass'); grunt.loadNpmTasks('grunt-contrib-csslint'); grunt.loadNpmTasks('grunt-contrib-cssmin'); grunt.loadNpmTasks('grunt-contrib-copy'); // Default task. grunt.registerTask('default', ['watch', 'sass', 'csslint', 'cssmin', 'copy']); };

I will not going into detail about what all this tasks do. Maybe in a future tutorials about Grunt plugins. However, I will explain roughly what these lines do.

I simplified the file reducing the tasks for explaining purposes:

module.exports = function(grunt) { // Project configuration. grunt.initConfig({ // Metadata. pkg: grunt.file.readJSON('package.json'), watch: { sass: { files: ['sass/*.scss', 'sass/components/*.scss'], tasks: ['sass'], options: { livereload: true } }, sass: { dist: { files: [ {'output/index.css': 'sass/index.scss'} ] } }, }); // These plugins provide necessary tasks. grunt.loadNpmTasks('grunt-contrib-watch'); grunt.loadNpmTasks('grunt-contrib-sass'); // Default task. grunt.registerTask('default', ['watch', 'sass']); };

This file reads the package.json file to know what versions of plugins we need Grunt must run, watch the folder /sass/ and /sass/components/ to see when any SCSS file is updated and, then, launch the task sass.

The sass task compile the file index.scss to index.css. In this example, all SCSS files should be imported in the index.scss file using the import directive.

With the next lines, we load the plugins to they can run:

grunt.loadNpmTasks('grunt-contrib-watch'); grunt.loadNpmTasks('grunt-contrib-sass');

And finally, we register a default task to run when we type grunt from the shell anywhere in our project path.

grunt.registerTask('default', ['watch', 'sass']);

This is an extremely simple Gruntfile with a minimum set of actions but the possibilities are huge. We can combine and concatenate files, minifiy them, compile coffescript files, run template engines like Jade or Handlebars, improve the QA of our code runing JSLint and CSSLint analysis after we save our files and much more. The combinations and posibilities are awesome and we can’t do it manually without an incredible amount of time wasted.

Run our Grunt tasks

Once we have our package.json and Gruntfile.js files configured, we only need run the commando grunt from the shell anywhere in our project folder or subfolders.

If we have a watch task, you should see a message waiting… in the console so Grunt is waiting to you modify the files you configure in the Gruntfile.

If you have a set of actions without watch, Grunt begins to run these actions in the order your write in the Gruntfile.

Conclusion

Grunt improves many areas of our life as developers.

  • Improves the QA of our code helping us introducing a lot of QA tools automatically in our workflow and with a couple of lines of configuration.
  • Reduce the possibility of errors automating the proccess of publishing, copying files and folders we need without our intervention.
  • Lets us use a huge amount of tools automatically that we couldn’t use manually without wasting huge amounts of time.

I can guarantee you it’s not necessary more than 2 hours to install, configure and understand your first Grunt instance. You will appreciate that.

It’s an advice from a front-ender. In the next months and years a lot of more tools comes and we need any way to automate it to have enough time to know them and keep us up.

Originally published at www.frontdojo.com.

--

--

Alex R Chies
Across the mirror

Product Designer, UI Architect and Scrum Master at @stratiobd, passionate for standards and accessibility. Follow me as @alexrchies