Tutorial. Primeros pasos con Grunt

31/01/2016

Hoy inicio un serie de tutoriales hablando de Grunt, una herramienta en javascript que mediante unos plugins nos permitirá automatizar todas aquellas tareas repetitivas que nos hacen un perder un tiempo valioso. Para poder usarlo necesitamos el gestor de paquetes npm y grunt-cli - este ultimo instalado de manera global - con el siguiente comando:

sudo apt-get install npm && npm install -g grunt-cli

Ahora instalaremos Grunt y un plugin grunt-cssano, cuyo cometido es reducir el tamaño de los ficheros CSS. Todo este proceso se dividirá en dos partes para evitar malos entendidos, la instalación y su posterior configuración.

1º La instalación. Creamos una carpeta en nuestro escritorio de nombre grunt_tutorial, en su interior generamos un fichero de nombre package.json donde alojaremos Grunt y el plugin grunt-cssnano dentro de la etiqueta devDependencies. La versión de Grunt va precedida de un ~ para puntualizar que queremos usar una versión concreta (0.4.5) mientras que con * forzaremos la ultima versión disponible de grunt-cssnano.

{
    "name": "grunt",
    "version": "1.0.0",
    "description": "Grunt",
    "devDependencies": {
        "grunt": "~0.4.5",
        "grunt-cssnano": "*"
    }
} 

Abrimos una terminal en la carpeta grunt_tutorial y ejecutamos el siguiente comando para instalar todo el contenido de devDependencies en la carpeta node_modules y, de ese modo, comenzar a usar Grunt:

npm install

2º La configuración. Creamos Gruntfile.js en grunt_tutorial, su estructura se divide en tres partes fundamentalmente. La zona de variables globales, la zona intermedia donde configuraremos los plugins y la zona final donde registraremos los plugins que consideremos oportuno usar.

module.exports = function (grunt) {

    /* zona de variables */

    grunt.initConfig({

    /* configuracion de plugins */

    });

    /* registro de tareas */

};

Así quedaría la configuración de nuetro plugin cssnano. Tenemos un subproceso "default" que tratara el fichero /css/style.css para reducirlo de tamaño y guardarlo en /css/result.css. En resumen, la variable src fija el puntero donde esta el fichero, mientras que dest apunta al lugar donde queremos dejar el fichero ya tratado.

module.exports = function (grunt) {

    grunt.initConfig({

        cssnano: {
        /* Creamos un subtarea default */
            default: {
               /* archivos que tratar */
                files: [{
                    expand: false,
                    src: 'css/style.css',
                    dest: 'css/result.css'
    }]
            }
        }

    });
    /* Registro del plugin. Muy importante */
    grunt.loadNpmTasks('grunt-cssnano');
};

Tan solo nos quedaría probar si funciona. Dentro de la carpeta grunt_tutorial creamos una carpeta de nombre CSS en cuyo interior pondremos un fichero style.css para respetar la variable src y escribiremos dentro lo siguiente:

.class {
  background-color: #f3f3f3;
  width: 100px;
  height: 100px;
  font-color: #000;
}

Desde la misma terminal abierta en grunt_tutorial podemos lanzar el siguiente comando para probarlo:

grunt cssnano

Si todo ha ido bien obtendremos un result.css en la carpeta css con este aspecto reducido:

.class {
  background-color: #f3f3f3;
  width: 100px;
  height: 100px;
  font-color: #000;
}
Crear subtareas

Como habéis podido comprobar, nuestra subtarea default esta muy limitada, pero veréis que con unas simples modificaciones podemos mejorarla a nuestro antojo.

Los CSS de una carpeta. Activamos expand a true para buscar recursivamente cualquier fichero. Por ultimo, la variable src se sustituye por 'css/*.css' para indicar que todos los ficheros con extensión *.css de la carpeta css serán tratados. En la carpeta dest obtendremos el resultado respetando la estructura de carpetas según vaya encontrándolos.

folder: {
        files: [{
        expand: true,
        src: 'css/*.css',
        dest: 'dest'
        }]
}   

Los CSS de carpetas & subcarpetas. Parecido al caso anterior pero con la salvedad de que la variable src contiene dos asteriscos para puntualizar que queremos que busque también en subcarpetas de la ruta css.

subfolder: {
           files: [{
           expand: true,
           src: 'css/**/*.css',
           dest: 'dest'
           }]
}   

Sobrescribir los CSS. Removiendo la variable dest obtendremos una subtarea que sobrescribe todos los ficheros *.css que estén en la carpeta css y subcarpetas.

overwrite: {
           files: [{
           expand: true,
           src: 'css/**/*.css'
           }]
}    

Así quedaría nuestro fichero Gruntfile.js con la subtarea overwrite a modo de ejemplo. Al final del fichero podreis ver un registerTask, esa linea nos permite crear una tarea personalizada de nombre "sobrescribir" para ejecutar exclusivamente la subtarea overwrite de cssnano.

module.exports = function (grunt) {
  grunt.initConfig({
    cssnano: {
      /* Creamos un subtarea default */
      default: {
        /* archivos que tratar */
        files: [
          {
            expand: false,
            src: 'css/style.css',
            dest: 'css/result.css',
          },
        ],
      },
      /* Nueva subtarea */
      overwrite: {
        files: [
          {
            expand: true,
            src: 'css/**/*.css',
          },
        ],
      },
    },
  })
  /* Registramos el plugin */
  grunt.loadNpmTasks('grunt-cssnano')
  /* Registramos una tarea de nombre sobreescribir 
    grunt.registerTask('nombre_personalizado',['cssnano:(subtarea de cssnano)']);
    */
  grunt.registerTask('sobrescribir', ['cssnano:overwrite'])
}

Si queremos ejecutar cssnano con todas sus subtareas incluidas (default y overwrite) tendremos que ejecutar:

grunt cssnano

Y si solo queremos ejecutar la subtarea overwrite:

grunt sobreescribir /* o también grunt cssnano:overwrite */

En este tutorial hemos hablado exclusivamente de grunt-cssnano pero el listado de plugins para grunt es prácticamente infinito. Si os pica el gusanillo con Grunt podéis trastear con los plugins mas populares pulsando en el enlace de aquí abajo.

Listado de plugins para Grunt