La verdad que lo vengo usando en prácticamente cualquier cosa que hago con javascript, sea solo cliente, server o ambas. Así que decidí escribir un post de esta interesante herramienta.

gruntjs

Grunt JS

Es una aplicación NodeJS, que a través de un archivo de configuración (el Gruntfile.js) ejecuta tareas que pueden ir desde copiar archivos, minificar js, correr tests, cobertura de código, observar cambios tus scripts, etc … hasta tareas personalizadas que te haces simplemente escribiendo javascript (node js).

Beneficios

Acceso a archivos
Tiene resulto el sistema de acceso a archivos, solo tenemos que ocuparnos de configurar las rutas y que hacer con los archivos cuando la tarea corre.
Automatización
Podemos dejar un set de tareas configuradas en orden de ejecución y luego es simplemente correr el comando grunt.
Fácil instalación
Esta en NPM, la instalación es simplemente un npm install.
Plugins comunitarios
Como los plugins de jQuery, los hacemos en comunidad, pero los dejamos en NPM, por lo que solo agregando una referencia a nuestro package.json y con un npm install usamos el plugin que necesitamos. Ya tiene una gran cantidad de plugins hechos y hacer los nuestros es muy fácil.
Multi-plataforma
Si bien esto no es un beneficio directo de Grunt, es muy común que las cosas que podemos hacer con Grunt las hagamos en un Makefile o un BAT, por eso lo tomo como un beneficio, al correr en node y ser javascript podemos tener nuestro set de tareas funcionando en cualquier sistema operativo.

Instalación

Como mencioné antes, está en NPM. (y necesitamos NodeJS instalado).

Primero instalamos el “cliente” de Grunt de forma global, es el encargado de fijarse por nosotros que versión de grunt tiene el proyecto en el que lo estamos corriendo:

npm install grunt-cli -g

El parámetro -g indica que lo instalamos global del usuario actual en el sistema operativo.

Luego instalamos el paquete grunt (el que corre las tareas) en el proyecto de forma local:

npm install grunt --save-dev

Le agregamos –save (para que lo inserte en las dependencias del package.json) y -dev para que sea en las dependencias de desarrollo, ya que vamos a necesitar grunt en tiempo de diseño o desarrollo, no en tiempo de ejecución de nuestra aplicación.

Si miramos nuestro package.json:

{
  "name": "nombre",
  "version": "0.0.1",
  "dependencies": { 

  },
  "devDependencies": {
    "grunt": "~0.4.1"
  }
}

Creando el Gruntfile

Ahora agregamos un archivo al root, en el mismo lugar que tenemos el package.json con el nombre Gruntfile.js:

module.exports = function(grunt) {
  // Aca vamos a armar nuestras tareas
};

Y que es este archivo?, simplemente un modulo de NodeJS, el cual va a ser llamado por grunt cuando lo ejecutemos pasándonos por parámetro grunt el acceso al paquete para agregar las tareas y configuraciones.

Hagamos una prueba de nuestro Gruntfile.js registrando una tarea “Hola Mundo”:

module.exports = function(grunt) {

  grunt.registerTask('default', 'Tarea Hola Mundo', function() {
    grunt.log.write('Hola Mundo!').ok();
  });

};

Corremos grunt:

grunt

Simple!, registramos una tarea propia que muestre un “hola mundo” en la consola.

Sin meternos en mucho detalle de como realizar tareas personalizadas (ya que en la mayoría de los casos vamos a utilizar las creadas por la comunidad), vamos a probar una concatenación de scripts y su posterior minificacion:

GruntJS tiene como plugins básicos los grunt-contrib-*. Son un set de las tareas mas comunes para un proyecto y cada uno tiene su repositorio en github con documentación y código fuente. Para este ejemplo vamos a usar grunt-contrib-concat y grunt-contrib-uglify

Primero instalemos los paquetes npm:

npm install grunt-contrib-concat --save-dev
npm install grunt-contrib-uglify --save-dev

y ahora pongamos nuestra configuracion en el Gruntfile.js:

module.exports = function(grunt) {
  // este método que nos da Grunt es para pasarle las configuraciones a los paquetes que usemos
  grunt.initConfig({
    concat: {
      all: {
        src: "./scripts/**/*.js",
        dest: "./distribucion/todos.js"
      },
    uglify: {
      all: {
        src: "./distribucion/todos.js",
        dest: './distribucion/todos.min.js'
      }
  });

  // registramos las tareas (plugins) desde npm en Grunt
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-uglify');

  // registramos las tareas que se pueden ejecutar y el orden
  grunt.registerTask("default", [ "concat", "uglify" ]);
  grunt.registerTask("dist", [ "default" ]);
};

Y listo, ahora simplemente corremos

grunt

o

grunt dist

GruntJS tiene mucho mas en cuanto a configuraciones, plugins, etc. Pero meterse de lleno en todo lleva su tiempo y a medida que empiecen a usarlo van a ir descubriendo configuraciones nuevas, plugins y como crear tareas propias. Por ahora con esta intro pueden empezar a probar y les agrego algunos links para ampliar (son en inglés, pero con la base de este post, creo que siguiendo el código de ejemplo pueden meterse con nuevas tareas y configuraciones).

  1. Grunt
  2. Configurando Tareas
  3. Repositorios de los Grunt-contrib-*
  4. La inmensa lista de plugins
  5. Un proyecto mio con grunt y algunas de las configuraciones comunes