Grunt Example: Explore 6 Common Tasks You Need to Do

Compile LESS into CSS, concatenate JS files, watch changes, minify CSS, compile JavaScript with Babel and minify JavaScript in development or production mode.

Prerequisites to use Grunt

  1. install Node.js
  2. install Grunt globally, type into your command line: npm install -g grunt-cli

Folder structure

index.php
assets
     less
         main.less
         ...
     js
         jquery.3.2.1.js
         ...
         custom.js
    images
    dist
    Gruntfile.js
    package.json

where in package.json is configuration stored and in Gruntfile.js we define all the tasks. In “dist” folder we store CSS and JS files ready for use in production.

Configure package.json

{
     "name": "my-project-name",
     "version": "0.1.0",
     "devDependencies": {
          "babel-preset-es2015": "^6.24.1",
          "grunt": "0.4.5",
          "grunt-babel": "^6.0.0",
          "grunt-contrib-concat": "latest",
          "grunt-contrib-cssmin": "^2.2.0",
          "grunt-contrib-less": "^1.4.1",
          "grunt-contrib-uglify": "^2.3.0",
          "grunt-contrib-watch": "~0.6.1"
     }
}

Now, navigate into your project folder in command line and type npm install. All plugins are installed. If everything went smoothly, in the “Assets” there is a new folder called “node_modules” containing all necessary components to use.

Prepare Gruntfile.js

module.exports = function(grunt) {
 
 // Force use of Unix newlines
 grunt.util.linefeed = '\n'
 
 grunt.initConfig({
  pkg: grunt.file.readJSON('package.json'),

  watch: {
    scripts: {
      files: ['less/*.less', 'js/*.js'],
      tasks: ['less:dev', 'babel', 'concat:dev'],
      options: {
        interrupt: true,
        spawn: false,
      },
    },
  },

 concat: {
  dev: {
    src: [
      'js/jquery.3.2.1.min.js',
      'js/custom.js'
    ],
    dest: 'dist/custom.js'
  },
 },
 
 cssmin: {
  main: {
   expand: true,
   cwd: 'dist',
   src: ['*.css', '!*.min.css'],
   dest: 'dist/minified',
   ext: '.min.css'
  },
 },

 less: {
  options: {
   sourceMap: false
  },
  dev: {
   files: {
     'dist/styles.css': 'less/main.less'
   }
  }
 },

 babel: {
  options: {
    sourceMap: false,
    presets: ['es2015']
  },
  dist: {
    files: {
     'js/custom.js': 'js/es6.js'
    }
  }
 },

 uglify: {
  main: {
    files: {
      'dist/minified/custom.min.js': 'dist/custom.js'
    }
   }
 }
});

grunt.registerTask('dev', ['less:dev', 'babel', 'concat:dev']);
grunt.registerTask('build', ['less:dev', 'babel', 'concat:dev', 'uglify:main', 'cssmin']);

grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-babel');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-cssmin');
};

In watch mode and also in “dev” registered task, there is not minification included. This is useful in development, when debugging is needed.

When you go to production, use “build” registered task, and you have nicely compiled and compressed CSS and JS files.

Take a look at index.php, how can loading different assets look like in development or production mode:

<?php
 define("DEVELOPMENT_MODE", true);
?>

<!DOCTYPE html>
<html>
<head>
 <title>Grunt example: explore 6 common tasks you need to do</title>
 <meta charset="UTF-8" />
 
 <?php if( DEVELOPMENT_MODE ){ ?>
   <link rel="stylesheet" href="assets/dist/style.css">
   <script src="assets/dist/custom.js"></script>
 <?php } else { // production ?>
   <link rel="stylesheet" href="assets/dist/minified/style.min.css">
   <script src="assets/dist/custom.min.js"></script> 
 <?php } ?>
</head>
<body>
</body>
</html>