Скажем, мы хотим, чтобы Grunt работал в процессе разработки, а затем, когда мы перейдём к рабочему сайту, нам потребуются другие задачи для выполнения. Мы можем определить несколько задач внутри каждой конфигурации. Например:
// Gruntfile.js
grunt.initConfig({
  // получить конфигурацию из package.json 
  // так мы можем использовать штуки вроде name и version (pkg.name)
  pkg: grunt.file.readJSON('package.json'),
  ...
  // параметры uglify для минимизации JS-файлов
  uglify: { 
    options: { 
      banner: '/\n <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> \n/\n' 
    }, 
    dev: { 
      files: { 'dist/js/magic.min.js': ['src/js/magic.js', 'src/js/magic2.js'] } 
    }, 
    production: { 
      files: { 'dist/js/magic.min.js': 'src/**/*.js' } 
      } 
    }
});
Теперь мы можем вызвать их по-разному, используя двоеточие. Давайте создадим задачу для разработки и публикации.
// Gruntfile.js
grunt.initConfig({
  // ========= // СОЗДАЁМ ЗАДАЧИ =========
 
  // задача по умолчанию проходит через все конфигурации (dev и production) 
  grunt.registerTask('default', ['jshint', 'uglify', 'cssmin', 'less']);
  // эта задача будет выполняться только для конфигурации dev
  grunt.registerTask('dev', ['jshint:dev', 'uglify:dev', 'cssmin:dev', 'less:dev']);
  // только для конфигурации production
  grunt.registerTask('production', ['jshint:production', 'uglify:production', 'cssmin:production', 'less:production']);
});
Теперь мы можем выполнить задачи для разработки запустив:
$ grunt dev
Или задачи для рабочего сайта запустив:
$ grunt production
Как видите, мы можем создать несколько конфигураций для наших задач и по разному вызывать их. 
И последняя вещь, которую мы сейчас изучим. Будем следить за файлами и запускать Grunt каждый раз при их изменении!