Grunt

Introducción a grunt por Daniel Rodríguez

Shiraga Kazuo

archivado en: JavaScript / 24 septiembre, 2014

Daniel Rodríguez envía otro tutorial, en este caso sobre grunt, una herramienta formidable para trabajar con javaScript.

Grunt nos permite simplificar nuestros proyectos en JavaScript aportándonos métodos para simplificar, comprimir, depurar nuestro código o ayudarnos con comandos de nuestro sistema operativo.

Instalación

Para instalar Grunt necesitamos tener instalado Node.js. Para ello lo abrimos con privilegios de administrador y ejecutamos:

$ npm install -g grunt-cli

Con esto no instalamos Grunt, sino una interfaz que permite ejecutar la versión correcta de Grunt dependiendo del proyecto en el que estemos.

Nos creamos donde queramos una carpeta con un nombre que queramos darle, por ejemplo “miproyecto”.
Ahora necesitaremos un archivo llamado package.json, cuyo fin será documentar el paquete Grunt dentro de Node.js. Dentro de él tendremos que tener estas líneas:

{

"name": "MiProyecto",

"version": "0.1.0",

"devDependencies": {

"grunt": "~0.4.5",

"grunt-contrib-jshint": "~0.10.0",

"grunt-contrib-concat": "~0.4.0",

"grunt-contrib-uglify": "~0.5.0",

"grunt-shell": "~0.7.0"

}

}

Como vemos le hemos dado un nombre y una versión a nuestro proyecto. También le indicamos que son necesarias para el mismo algunas dependencias, las cuales se tendrá que bajar, como es el caso de Grunt, jshint (usado para análisis de código), concat (para mezclar dos o más archivos dentro de uno), uglify (para minificar archivos) y shell (para ejecutar comandos propios de nuestra consola del sistema operativo).

Guardamos este archivo dentro de “miproyecto” y lo cerramos.

Ahora con la consola nos vamos a la carpeta de “miproyecto” y escribimos:

$ npm install --save-dev

$ npm install -g grunt-init

Ahora ya tenemos Grunt correctamente instalado. Podemos comprobar que es así con:

$ grunt --version

Depurar

Vamos ya a empezar con la primera toma de contacto con Grunt.

Haciendo uso de la dependencia de jshint vamos a depurar un código de un archivo que tenemos guardado.

Para ellos metemos nuestro js en la carpeta “Proyectos” y además crearemos otro js más con la configuración de Grunt llamado gruntfile.js:

module.exports = function(grunt) {

// Configuración del proyecto

grunt.initConfig({

jshint:{

all:['controlador.js']

}

});

grunt.loadNpmTasks('grunt-contrib-jshint');

grunt.registerTask('default', ['jshint']);

}

Vemos que hemos especificado un “controlador.js”. Es el archivo que vamos a depurar. Podemos cambiarle el nombre si el nuestro se llama de otra forma.

loadNpmTasks indica la tarea que va a ser cargada. Como podemos ver es la misma línea que añadimos en el packaged.json.

En la última línea definimos jshint como la tarea a lanzar cuando Grunt se ejecuta en el modo por defecto.

Guardamos y cerramos este archivo y ya con este archivo y nuestro archivo js que queremos depurar, nos vamos a la consola y escribimos dentro de la carpeta donde están ambos archivos lo siguiente:

$ grunt

En mi caso me muestra un pitido al lanzar el comando y 2 errores:

grunt1
Vemos que nos dice que hay 2 errores, ambos iguales, uno en la línea 17 y otro en la 23, por una falta de punto y como.

Jshint es muy estricto en el tema de errores y no podemos saltarnos nada tan “tonto” como un punto y coma, aunque nuestro código funcione a la perfección.

Por lo tanto, ponemos esos 2 puntos y comas que nos faltan, guardamos y volvemos a escribir el comando:

grunt2

Bien. Ya tenemos nuestro js limpio de errores de código.

Mezclar

Como especificamos al inicio en el packaged.json, concat sirve para unificar archivos, reduciendo su peso y aligerando posteriormente la carga de la web o aplicación.

Para ello vamos a aumentar el código de nuestro ya conocido gruntfile.js:

module.exports = function(grunt) {

// Configuración del proyecto

grunt.initConfig({

jshint:{

all:['controlador.js']

},

concat: {

dist: {

src: ['controlador.js', 'script1.js', 'script2.js'],

dest: 'unidos.js'

},

}

});

grunt.loadNpmTasks('grunt-contrib-jshint');

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

grunt.registerTask('default', ['jshint', 'concat']);

}

Apreciamos un nuevo bloque debajo de jshint, el de concat, al cual le pasamos 3 archivos que queremos fusionar en uno (si estuvieran en otro sitio se lo indicaríamos en la ruta junto al nombre, estos archivos a comprobar y a unir los estoy metiendo en esta carpeta para no alargar el código del gruntgile.js con rutas) y en “dest” le indicamos el nombre del archivo resultante ya mezclado.

Pero como explicamos anteriormente esto no funcionará hasta que no le digamos que la tarea ha de ser cargada, cosa que hace la loadNpmTasks, por lo tanto habrá que añadirle la línea de contact también.

Definidas la tarea, debemos cargar el plugin (última línea).

Volvemos ya a ejecutar el comando $ grunt en nuestra consola y este es el resultado:

grunt3

Y evidentemente, tenemos también un archivo más, llamado unidos.js, que es el resultado de la suma de los otros 3 archivos.

Podemos sumar cuantos queramos, obviamente, no tienen por qué ser tres.

Minimizar

El siguiente proceso a incluir en nuestro archivo de configuración de Grunt es el de minimizado de archivos.

Muchos habremos trabajado con librerías de javaScript llamadas “librería.min.js”. Como bien sabemos, son javaScripts “minifield”, comprimidos a pocas líneas para acelerar su carga en nuestras aplicaciones o webs.
Son las versiones más recomendables si no vamos a trabajar directamente en ellas, con lo cuál necesitaríamos su código sin compresión alguna.

Esto es lo que hace uglify. Nos crea una archivo .js minificado de menos peso.

Así que de nuevo vamos a incluir más código en nuestro gruntfile.js:

module.exports = function(grunt) {

// Configuración del proyecto

grunt.initConfig({

jshint:{

all:['controlador.js']

},

concat: {

dist: {

src: ['controlador.js', 'script1.js', 'script2.js'],

dest: 'unidos.js'

}

},

uglify: {

dist: {

src: 'unidos.js',

dest: 'build/unidos.min.js'

}

}

});

grunt.loadNpmTasks('grunt-contrib-jshint');

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

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

grunt.registerTask('default', ['jshint','concat','uglify']);

}

Debajo de concat hemos añadido el nuevo bloque de uglify de una forma bastante similar (por no decir igual) que hicimos con concat: localización del archivo a simplificar y destino.

Los bloques de abajo no creo que necesiten ya más explicación.

Por lo tanto volvemos a ejecutar $ grunt para que ejecute el código:

grunt4

Ningún error como vemos. Si hubiese algo más escrito nos indicaría el qué y dónde.

Si vamos ahora a la carpeta que hemos puesto como destino veremos que hay un nuevo archivo llamado “unidos.min.js”. Si lo abrimos veremos cómo ha pasado todo nuestro código a una sola línea.

Comandos

La última dependencia a probar de nuestro packaged.json es shell, que como explicamos son comandos que le añadimos de nuestro propio sistema operativo, como cortar, mover, crear, borrar, etc.

Para ello añadimos otro bloque de configuración en nuestro gruntfile.js como ya sabemos.

shell: {

multiple: {

command: [

'del unidos.js',

'mkdir deploy',

'movebuild\\unidos.min.js deploy\\unidos.min.js'

].join('&&')

}

}

No creo que haga falta a estas alturas poner el código entero, ya que estamos bastante acostumbrados a él y a este proceso. Sólo ponedlo debajo del bloque de uglify (sin olvidarse de añadir una coma después de este). Sí procederé a explicarlo un poco:

  • La llave múltiple terminada en join indica que vamos a cargar más de un comando a la vez.
  • Vemos 3 comandos simples: del (borrado de archivo), mkdir (creado de carpeta) y movebuild (mueve un archivo de un destino a otro).
  • Como vemos, tanto los comando como las barras dobles para la izquierda son propios de Windows. Esto quiere decir que si lo ejecutáramos en Linux deberíamos usar sus comandos. Yo como uso Windows pongo el jemplo así.

Cargamos la tarea y la registramos:

grunt.loadNpmTasks('grunt-shell');

grunt.registerTask('default',['jshint','concat','uglify','shell']);

Volvemos a ejecutar $ grunt en la consola y vemos el siguiente resultado:

grunt5

Aparece una nueva línea al final haciendo referencia a shell e indicando que se ha movido un archivo. Y aunque no aparezca, el archivo unidos.js también ha sido eliminado.

Hemos hecho unas prueba con comandos de consola muy simples, pero podríamos hacer algo más complejo con muchos más comandos y trabajando con cientos de archivos a la vez.

¿Pero qué pasaría si hay veces que queremos sólo depurar el código y nada más? ¿Tendríamos que editar el gruntfile.js y volver a cambiarlo más tarde?

Pues no, podemos ejecutar una sola tarea en vez de todas a la vez como estamos haciendo desde el principio.

Si ponemos por ejemplo $ grunt jshint veremos que nos hace sólo el bloque de jshint:

grunt6

Si quieres profundizar sobre Grunt y aprender muchas más cosas te dejo un enlace a su web donde podrás encontrar infinidad de plugins (que podrás incluir en tu package.json como nuevo bloque) que la comunidad va creado.

|| Tags: ,

Este artículo aún no ha sido valorado.

¿Te ha parecido útil o interesante esta entrada?
dormido, valoración 1 nadapensativo, valoración 2 un poco sonrisa, valoración 3 a medias guiño, valoración 4 bastante aplauso, valoración 5 mucho

Tú opinión es muy importante, gracias por compartirla!

Los comentarios están cerrados.