Skip to Main Content

Grunt and Front End Development

I've heard a lot about Grunt.js and Gulp.js over the last year. It's been on my todo list of things to learn. Last week I jumped in with some help from Tad Ward via Skype.

I've heard a lot about Grunt.js and Gulp.js over the last year. It's been on my todo list of things to learn. Last week I jumped in with some help from Tad Ward via Skype.

I initially struggled as I had a project I was about to take on that was using gulp and I misunderstood what was needed. Turned out the files I was given were more examples of what was needed rather than me working with the existing code. Once I got that figured out, I decided to keep looking into both Grunt and Gulp. In the end I decided that Grunt looked easier for more.

I had previously installed Node and work in Git and Compass on all my projects so most of the requirements to get running were already set up on my system. Currently I've only got a testing project setup but how I see it working is that I open up a command prompt with Administrator permission (requires administrator permissions on Windows, not sure about Mac) and navigate to the project folder and then type npm init. There there will be some prompts that you need to fill out then you bare project is set.

The next step is to run the command:

    
      npm install grunt --save-dev
    
  

The --save-dev installs grunt to this particular project. Once this is done, you then install the other grunt tasks that you want to run. The ones that I want to work with are Compass, Uglify, Watch and Concat. Next type the following commands:

    
      npm install grunt-contrib-compass --save-dev
npm install grunt-contrib-uglify --save-dev
npm install grunt-contrib-watch --save-dev
npm install grunt-contrib-concat --save-dev
    
  

Next up we need to create a gruntfile which loads the commands and tasks that will be run. Through a lot of trial and error my working gruntfile is here:

    
      module.exports = function(grunt) {
 
// Project configuration.
grunt.initConfig({
 pkg: grunt.file.readJSON('package.json'),
// CONFIG ===================================/
 
	watch: {
		compass: {
			files: ['**/*.{scss,sass}'],
			tasks: ['compass:dev']
		},
		js: {
			files: ['build/js/**/*.js', 'bower_components/*.js'],
			tasks: ['uglify', 'concat']
		},
 
		livereload: {
			options:{livereload:true},
			files:['css/*', '*.html', 'templates/**/*.html'],
		}
	},
 
	compass: {
		dev: {
		   options: {              
		       sassDir: ['build/sass'],
		       cssDir: ['css'],
		       environment: 'development'
		   }
		},
		prod: {
		   options: {              
		       sassDir: ['build/sass'],
		       cssDir: ['css'],
		       environment: 'production',
		       outputStyle: 'compact'
		   }
		},
 
	},
 
	uglify: {
		dev:{
			options:{
				compress: {
					drop_console: false
				}
			},
			files: {
		      'js/main.min.js': [
		      'build/js/*.js', 
		      'build/js/**/*.js'
		      ]
		  }
		},
		prod: {
			options:{
				compress: {
					drop_console: true
				}
			},
			files: {
		      'js/main.min.js': [
		      'build/js/*.js', 
		      'build/js/**/*.js'
		      ]
		  }
		},
 
	},
 
	// concatenate js and output unminified.
	concat: {
	    options: {
	      separator: '\r\n\r\n /******/ \r\n\r\n',
	    },
	    dist: {
	      src: ['build/js/*.js', 'build/js/**/*.js'],
	      dest: 'js/main.js',
	    },
	},
 
 
 
});
 
// DEPENDENT PLUGINS =========================/
 
grunt.loadNpmTasks('grunt-contrib-watch');
 
grunt.loadNpmTasks('grunt-contrib-compass');
 
grunt.loadNpmTasks('grunt-contrib-uglify');
 
grunt.loadNpmTasks('grunt-contrib-concat');
 
 
// TASKS =====================================/
 
grunt.registerTask('default', ['compass:dev' , 'uglify:dev' , 'concat', 'watch']);
 
};
    
  

What happens here is that the watch command Sets up files to watch and tasks to do. First it runs compass so that my Sass files get processed and output to the folders indicated in the Compass command below. Next in Watch js is uglified, i.e. compressed and concatenated. Lastly I use Concat to concatenate all the js files and output a version that is not minified. The minified version will be used in production. Line 76 adds line breaks between concatenated files for easier readability.

I do a lot of work for other agencies and feel that I should also provide them with a readable version of the javascript which this accomplishes. Now grunt outputs a main.js and a main.min.js file to the /js/ folder.

Back to the Watch command on line 18 we see:

    
      livereload: {
	options:{livereload:true},
	files:['css/*', '*.html', 'templates/**/*.html'],
}
    
  

This is pure gold. Before I got this working I had gone after a red herring, grunt-browser-sync, which would never install and led to much frustration. Once I found the docs for Live Reload and set it up to reload css/js/html on change I was set. This command actually watches the CSS file for change. So once compass processes the Sass files and outputs the new CSS file then the browser reloads. There is a slight delay, but it is nice not having to manually refresh the page. To get it to work on your local files you need to either add a bit of javascript to the site or use a browser extension (Safari, Chrome, FireFox). Now all I do is make a change to the sass files, wait a second and the change is reflected on the site locally. No need for me to manually refresh the browser. This is brilliant. *UPDATE* - changed files for livereload and now works when developing in ExpressionEngine. I have my templates folder at public_html/templates - the /**/ is needed so that it will look for all html files inside all subdirectories.

When it's time to start development in the in the Command Prompt all you do is type grunt and then it performs the tasks set up on line 101.

    
      grunt.registerTask('default', ['compass:dev' , 'uglify:dev' , 'concat', 'watch']);
    
  

Now when I'm ready to move the code to production I can run different commands for example grunt compass:prod will run the compass task but instead of adding line comments and keeping the css readable everything will be compressed with no comments. Additionally running grunt uglify:prod will take care of the js files and remove all console.logs, which are not really necessary on production.

Assuming you have a number of tasks that you like to use on every site, this whole process will be even easier. All you need to do is copy package.json and gruntfile.js of an existing project into a new project folder. Then open up your command prompt with administrator permission and navigate to the new folder and then enter this command:

    
      npm install
    
  

Voila everything is installed and you are set to start developing. Comments and suggestions on tasks that may be useful to me or better approaches are appreciated.