Grunt scripts

What is Grunt?

Scripts for frequents tasks such as minify, compile and test.

Install via npm

1
npm install -D grunt

Configuration

via Gruntfile.js file in the actual directory, or the nearest directory if there is none.

  • The console for grunt is Grunt-cli and it can be installed with npm:

    1
    npm install –D -g grunt-cli
  • Parameters for “Grunt-cli”:

    • --gruntfile: specify path for Gruntfile.js
    • --force: forces to continue after errors
    • --tasks: extra dir to scan for finding new taks
    • --npm: scans the new grunt plugins installed with npm to search for new tasks
    • --verbose: show more information about the program execution

Tasks

  • A task is a set of commands which will be executed by grunt: if there is none, we will launch ‘default’.
  • Tasks should be installed via npm before being registered
  • The tasks configurations are set in grunt.initConfig(). Object keys are the tasks names (see line 40)
  • Tasks are loaded in the scheduler following the pattern (see also line 44): grunt.registerTask(taskName, [description, ] tasklist);
  • Multitasks are supported :grunt.registerMultiTask(taskName, [description, ] taskFunction)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
module.exports = function(grunt){
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
concat: {
options: {
separator: ';'
},
dist: {
src: ['src/**/*.js'],
dest: 'dist/<%= pkg.name %>.js'
}
},
uglify: {
options: {
banner: '/*! <%= pkg.name &> <%= grunt.template.today("dd-mm-yyyy") %> */\n'
},
dist: {
files:{
'dist/<%= pkg.name %>.min.js' : ['<%= <concat.dist.dest %>']
}
},
jshint: {
files: ['Gruntfile.js', 'src/**/*.js', 'test/**/*.js'],
options: {
//options here to override JSHint defaults
globals: {
jQuery: true,
console: true,
module: true,
document: true
}
}
},
watch: {
files: ['<%= jshint.files %>'],
tasks: ['jshint', 'qunit']
}
});

grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.registerTask('mytest', ['jshint']);
grunt.registerTask('default', ['jshint', 'concat', 'uglify']);
}
};
  • We can call subtasks of a multitask directly
    1
    2
    grunt concat //executes a multitask
    grunt concat:foo //executes the foo sutask, which is part of concat
  • Tasks can call asynchronous functions.
    1
    2
    3
    4
    5
    grunt.registerTask('asyncme', "My asynchronous task", function(){
    // done will be executed once the task is finished
    var done = this.async();
    doSomethingAsync(done);
    }

Mapping files

  • Parameters:

    • src: source path
    • dest: destination path
    • filter: file system native functions, to filter the files to load (e.g. supports the ** from the relative paths)
    • nonull: if true, it will include files which wont pass the filter
    • dot: add files whose name starts with the chracter ‘.’
    • matchbase: if it’s defined, the files will be searched starting on this dir
    • expand: processes a dynamically the src & dest mapping
  • Different file formats to define a task:

    • Compact
      1
      2
      3
      4
      5
      6
      grunt.initConfig({
      jshint: {
      foo: {
      src: ['src/aa.js', 'src/aaa.js']
      }
      },
    • Object
      1
      2
      3
      4
      5
      6
      7
      8
      grunt.initConfig({
      concat: {
      foo: {
      files: {
      'dest/a.js': ['src/aa.js', 'src/aaa.js'],
      'dest/a1.js': ['src/aa1.js', 'src/aaa1.js']}
      },
      },
    • Array
      1
      2
      3
      4
      5
      6
      7
      8
      grunt.initConfig({
      concat: {
      foo: {
      files: [
      {src: ['src/aa.js', 'src/aaa.js'], dest: 'dest/a.js'},
      {src: ['src/aa1.js', 'src/aaa1.js'], dest: 'dest/a1.js'}
      ],
      },
  • Dynamic mapping: we can even combine normal and dynamic mapping: we need to set the expand value to true

    • cwd: ruta del directorio donde se cargan los archivos
    • src: regex to load files
    • dest: destination to save the file
    • ext: reeplaces the file extension of the generated files
    • extDot: points out where is the file extension
    • flatten: deletes all the filepaths from the generated files
    • rename: describes a function which returns a String with the new file src and dest
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      files: [
      {
      expand: true,
      cwd: 'lib/',
      src: ['**/*.js'],
      dest: 'build/',
      ext: '.min.js',
      extDot: 'first'
      },
      ],

Example

Step by step

  1. If we need to load any external JSON property we can get its content into a var via
    1
    grunt.file.readJSON('package.json')
  2. We can call any grunt property directly via
    1
    grunt.config.requires('meta.name')
  3. There are Grunt templates so we can use tags <%= pkg.myvar %>
  4. To load Grunt tasks from npm we can use loadNpmTasks(‘myTaskName’) o loadTasks(‘myTaskName)
  5. Once loaded, we can register the defined task vis grunt.registerTask()
  6. We export the grunt mocule with all the configuration: module.exports = function(grunt) {…}

In a project

  • Gruntfile.js should be at the root folder
  • On node_modules we can see al the Grunt-related modules, which start with grunt-*
  • We can also this dependencies in package.json on devDependences
  • To implement Grunt in any project with the grunt-init module we can create basic templates to start with. Don’t forget to configure its Gruntfile.js

So if we have:

1
2
3
module.exports = function(){
return true;
}

And run grunt myTest with the following Gruntfile.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
module.exports = function(grunt){
grunt.initConfig({
uglify: {
src: {
files: [{
expand: true,
cwd: 'src',
src: '*.js',
dest: 'js-min/',
ext: '.min.js'
}]
}
}
});
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.reguisterTask('test', ['uglify']);
};

We get as an output js-min/myTest.min.js

1
2
3
module.exports = function(){
return !0;
}

Other examples of defined task

1
2
3
grunt.registerTask('install', [], installTaks);
grunt.registerMultiTask('packgrInstall', 'Download all the assets from dependencies',
function(){installTask(grunt, this); });