Visual Studio 2015 trajo muchas novedades, y vinieron muchas otras novedades para los desarrolladores con la salida de ASPNET Core, algunas de esas novedades las comenté anteriormente en el post Una nueva era de desarrolladores Web .Net, una de esas novedades (aunque es posible utilizarla en versiones anteriores a VS 2015) es la posibilidad de utilizar herramientas para automatizar y crear tareas para los archivos cliente, una de ellas es Grunt y es la que quiero explicar en este post.

Grunt

Grunt permite realizar tareas repetitivas para como minificación, compilación, validación de código entre otras de una forma sencilla, no voy a entrar en el detalle técnico del cómo funciona Grunt, eso lo puedes ver en la página oficial, la idea del post es mostrar como iniciamos con Grunt en Visual Studio 2015.


Lo primero, es crear un nuevo proyecto de tipo Web Application, y en ASPNET 5 Templates seleccionamos Empty, si seleccionas la plantilla Web Application de la misma categoría, vas a encontrar que se usa Gulp (otra herramienta similar a Grunt).

Empty Template

El siguiente paso, es agregar un archivo de tipo NPM Configuration File, archivo que se usa para manejar los paquetes nodejs:

NPM Configuration File

Ahora, en el archivo package.json que se acabó de agregar, en la propiedad devDependencies vamos a agregar las dependencias a Grunt y a dos plugin, en este caso a concat para concatenar archivos y uglify para minificarlos, luego de agregar dichas dependencias nuestro archivo debe verse así:


{
    "version": "1.0.0",
    "name": "ASP.NET",
    "private": true,
    "devDependencies": {
        "grunt": "0.4.5",
        "grunt-contrib-concat": "0.5.1",
        "grunt-contrib-uglify": "0.11.0"
    }
}

Ahora, vamos a crear una carpeta scripts, y allí adicionaremos dos archivos JavaScript, en este caso los he nombrado module1.js y module2.js:

Scripts Folder

El código para module1 y module2 es simple, ya que la idea es mostrar como vamos a concatenar y minificar dichos archivos, el código es:


//module1.js
var module1 = {
    task1: function(){
        console.log('task 1');
    },
    task2: function () {
        console.log('task 2');
    },
    task3: function () {
        console.log('task 3');
    },
    task4: function () {
        console.log('task 4');
    }
}
//module2.js
var module2 = {
    task1: function(){
        console.log('task 1');
    },
    task2: function () {
        console.log('task 2');
    },
    task3: function () {
        console.log('task 3');
    },
    task4: function () {
        console.log('task 4');
    }
}

El siguiente paso, es agregar un archivo de configuración de Grunt, allí se van a definir todas las tareas a realizar:

Grunt Configuration File

Las tareas, se van a definir dentro de initConfig, la primera tarea que se va a crear es la de concatenación de archivos, para ello, anteriormente se cargó el plugin grunt-contrib-concat, definiendo la tarea tenemos:


module.exports = function (grunt) {
    grunt.initConfig({
        concat: {
            all: {
                src: ['scripts/module1.js', 'scripts/module2.js'],
                dest: 'scripts/combined.js'
            }
        }
    });
};

En la propiedad src, especificamos todos los archivos que se desean concatenar, y en dest el archivo destino.


La siguiente tarea que vamos a definir, es la que va a tomar el archivo generado del paso anterior, es decir combined.js y lo va a minificar para generar el achivo combined.min.js utilizando en este caso el plugin grunt-contrib-uglify, volvemos al archivo de configuración de Grunt y la añadimos:


module.exports = function (grunt) {
    grunt.initConfig({
        concat: {
            all: {
                src: ['scripts/module1.js', 'scripts/module2.js'],
                dest: 'scripts/combined.js'
            }
        },
        uglify: {
            all: {
                src: ['scripts/combined.js'],
                dest: 'scripts/combined.min.js'
            }
        }
    });
};

Al igual que con la tarea anterior, en src se especifica el origen, el archivo a minificar, y en dest el destino, es decir el archivo generado.

Finalmente, para que las dos tareas anteriores funcionen, se deben cargan los módulos que se agregaron en el package.json luego de la función initConfig:


module.exports = function (grunt) {
    grunt.initConfig({
        concat: {
            all: {
                src: ['scripts/module1.js', 'scripts/module2.js'],
                dest: 'scripts/combined.js'
            }
        },
        uglify: {
            all: {
                src: ['scripts/combined.js'],
                dest: 'scripts/combined.min.js'
            }
        }
    });

    grunt.loadNpmTasks('grunt-contrib-concat');
    grunt.loadNpmTasks('grunt-contrib-uglify');
};

Ahora, ya que tenemos listas las tareas, clic derecho en el archivo de configuración de Grunt y allí seleccionamos Task Runner Explorer:

Task Runner Explorer

En la ventana de tareas se listan las dos tareas que hemos definido, para ejecutarlas simplemente nos posicionamos sobre alguna de ellas, damos clic derecho y a continuación Run, si ejecutamos las dos tareas, vamos a obtener al final el archivo combined.min.js tal como se ha especificado:

Task Runner Explorer

Espero el post les sea de ayuda para iniciar con Grunt, en próximos post veremos otros plugins y como seguir trabajando con esta herramienta.

Saludos!