Observar archivos con Grunt contrib watch

Categories:

Grunt nos permite ejecutar tareas cuando algún archivo – que definamos – tenga alguna modificación.
Para poder realizar esto necesitamos instalar el módulo grunt-contrib-watch.

$ npm install grunt-contrib-watch
Instalar grunt-contrib-watch
Instalar grunt-contrib-watch

Una vez hecho esto confirmamos que grunt-contrib-watch se encuentre dentro de las dependencias en el archivo package.json de nuestro proyecto.

{
  "name": "demo",
  "version": "0.1.0",
  "private": "true",
  "description": "Crear un paquete json para utilizar grunt",
  "main": "index.html",
  "author": "eamexicano",
  "license": "MIT",
  "devDependencies": {
    "grunt": "^0.4.5",
    "grunt-contrib-watch": "^0.6.1"
  }
}

Ahora necesitamos modificar el archivo Gruntfile.js en tres partes:

  1. Incluir el plugin con la tarea watch.
  2. Registrar la tarea.
  3. Definir los parámetros de la tarea watch.
module.exports = function(grunt) {

  grunt.initConfig({ 
/*  3. Definir los parámetros de la tarea watch.  
   Más adelante vamos a detallar la configuración
*/
    watch: {}
  });

/* 1. Incluimos el plugin con la tarea watch. */
  grunt.loadNpmTasks('grunt-contrib-watch');     

/* 2. Registramos la tarea como predeterminada */
  grunt.registerTask("default", ['watch']);
};

Una vez hecho esto vamos a definir la configuración de la tarea watch.

En la tarea watch vamos a definir una propiedad – que se va a llamar archivos – que a su vez va a tener dos propiedades.

  1. files: El o los archivos que queremos observar.
  2. tasks: La(s) tarea(s) que se va(n) a ejecutar cuando alguno de los archivos definidos cambie.
      archivos: {
        files: ["js/*.js", "css/*.css"],
        tasks: ["tarea"]
       }

Antes de continuar con la configuración – que puede implicar incluir y configurar otros plugins – podemos probar si funciona nuestra configuración de watch al definir la funcionalidad de la tarea “tarea”.

Para esto, dentro del archivo Gruntfile.js registramos una tarea – tarea -. Como segundo parámetro definimos una función que es la que se va a ejecutar cuando se invoque la tarea.

   grunt.registerTask("tarea", function () {
     console.log("Tarea que se manda ejecutar cuando se modifica un archivo .css o .js dentro de su carpeta");     
   });

Así quedaría el archivo Gruntfile.js con la configuración de la tarea watch y con la tarea “tarea” definida.

module.exports = function(grunt) {

  grunt.initConfig({ 
    watch: {
      archivos: {
        files: ["js/*.js", "css/*.css"],
        tasks: ["tarea"]
       }
    }
  });

  grunt.loadNpmTasks('grunt-contrib-watch');
  
   grunt.registerTask("tarea", function () {
     console.log("Tarea que se manda ejecutar cuando se modifica un archivo .css o .js dentro de su carpeta");     
   });
   
   grunt.registerTask("default", ['watch']);
};

Para probar que funciona invocamos la tarea grunt o grunt watch desde la línea de comandos.
Utilizamos grunt watch si existe(n) otra(s) tarea(s) definida(s) como predeterminada o default.

$ grunt

# Utilizar grunt watch si existe alguna tarea
# definida como predefinida.
# $ grunt watch

Una vez hecho esto en la línea de comandos grunt nos indica que está esperando “Waiting…” a que un cambio suceda en alguno de los archivos que está observando.

Después modificamos algún archivo – en este caso modifiqué el archivo demo.js -. Al guardar el archivo se puede visualizar en la línea de comandos el mensaje que definimos dentro de la tarea tarea.

Probar la configuración de la tarea watch
Probar la configuración de la tarea watch

Es probable que queramos tener tareas diferente para tipos de archivos diferentes. Entonces vamos a volver a definir la tarea watch. Ahora vamos a crear dos propiedades una va a ser para los archivos js y otra para los archivos css.

watch: {
      js: {
        files: ["js/*.js"],
        tasks: ["tarea_js"]
      },
      css: {
         files: ["css/*.css"],
         tasks: ["tarea_css"]
      }       
    }

Si queremos seleccionar únicamente algunos archivos podemos incluir dentro del arreglo files en cada propiedad el nombre del archivo separado por comas. Si queremos excluir algún archivo podemos indicar su ubicación y utilizar una negación antes del nombre.

watch: {
      js: {
        files: ["js/demo01.js", "js/demo02.js", "!js/demo.js"],
        tasks: ["tarea_js"]
      },
      css: {
         files: ["css/demo01.css", "css/demo02.css", "!css/demo.css"],
         tasks: ["tarea_css"]
      }       
    }

En este caso queremos observar los archivos demo01.css, demo02.css, demo01.js, demo02.js pero ignorar si hay cambios en demo.css y demo.js

Al igual que en el ejemplo anterior, definí las tareas tarea_js y tarea_css dentro del archivo Gruntfile.js

module.exports = function(grunt) {

  grunt.initConfig({ 
    watch: {
      js: {
        files: ["js/demo01.js", "js/demo02.js", "!js/demo.js"],
        tasks: ["tarea_js"]
      },
      css: {
         files: ["css/demo01.css", "css/demo02.css", "!css/demo.css"],
         tasks: ["tarea_css"]
      }       
    }
  });

  grunt.loadNpmTasks('grunt-contrib-watch');
  
   grunt.registerTask("tarea_js", function () {
     console.log("Tarea que se manda ejecutar cuando se modifica un archivo .js");     
   });

   grunt.registerTask("tarea_css", function () {
     console.log("Tarea que se manda ejecutar cuando se modifica un archivo .css");     
   });
   
   grunt.registerTask("default", ['watch']);
};

Puedes descargar el archivo Demo grunt watch que contiene los ejemplos de referencia:

  1. demo-09 – El archivo package.json incluye dependencia grunt-contrib-watch
  2. demo-10 – Configuración de la tarea watch utilizando la propiedad archivos para observar tanto los archivos css como los archivos js.
  3. demo-11 – Configuración de la tarea watch utilizando una propiedad para evaluar los archivos css y otra propiedad para evaluar los archivos js.

Para instalar las dependencias hay que utilizar npm install desde la carpeta del proyecto.

$ npm install