Encadenando tareas en gulp

Ya sabemos que gulp es un gestor de tareas. En un archivo gulpfile.js podemos crear tantas tareas como necesitemos, siempre y cuando, entre otros requisitos, hayamos instalado los plugins de gulp encargados de llevar esas tareas a cabo.

Sin embargo, las cosas no son siempre tan fáciles (en el mundillo de la programación, nada es tan fácil como parece). Si no tenemos un conocimiento real de cómo funciona gulp, podemos cometer errores que no sepamos cómo solucionar. En este artículo vamos a trabajar con un gestor con más de una tarea encomendada, y vamos a aprender un aspecto vital del uso de gulp. Los plugins que aquí usemos serán muy simples (uno de ellos, gulp-sass, ya lo hemos usado en artículos anteriores), pero nos van a permitir entender y asimilar un concepto de vital importancia en nuestro trabapo. Sigue leyendo, que este artículo te enseñará uno de los aspectos más relevantes de gulp.

EL ESCENARIO

Vamos a empezar definiendo el escenario. Tenemos, como en ejercicios anteriores, un documento web, llamado index.html. Sin embargo, en esta ocasión, no queremos que se cargue un archivo de hojas de estilos llamado styles.css, desde un directorio llamado css, sino la versión minificada del mismo, desde un directorio llamado min-css. Por lo tanto, lo primero que hacemos es crear el directorio min-css. Después, en index.html, sustituimos la siguiente línea:

<link rel="stylesheet" type="text/css" href="css/styles.css">

por:

<link rel="stylesheet" type="text/css" href="min-css/styles.css">

Por lo tanto, nuestro gestor de tareas debe llevar a cabo dos acciones cuando modifiquemos el sass: en primer lugar, compilarlo a css y grabarlo en la ruta css; en segundo lugar, minificar ese archivo resultante y grabar la versión minificada en la ruta min-css. Sabemos que la primera tarea la lleva a cabo el plugin gulp-sass, que ya tenemos instalado y ya hemos empleado. De la segunda tarea se encarga el plugin gulp-clean-css, que debemos instalar en nuestro proyecto. En la ruta raíz del mismo escribimos:

npm install --save-dev gulp-clean-css

Como ves, la instalación es idéntica a la que hicimos para gulp-sass, con la única salvedad del nombre del plugin que instalamos.

Ahora debemos modificar nuestro archivo gulpfile.js, para que lleve a cabo tres cosas que, hasta ahora, no teníamos:

  • Cargar el nuevo plugin en un objeto de gulp.
  • Implementar una tarea que lea el archivo css resultante de compilar el sass, y lo grabe en la ruta que deseamos.
  • El método gulp.watch() debe vigilar el archivo original en sass y, cuando este cambie, debe ejecutar las dos tareas: la que ya teníamos y la nueva que añadimos ahora.

Por lo tanto, el archivo del gestor de tareas queda así:

Usar este plugin es muy simple. Si observas las líneas detalladas con los comentarios del código, verás que no tiene mayor misterio. No obstante, el plugin ofrece, además, una serie de opciones complementarias, que puedes ver en este enlace. No voy a recargar este artículo detallándolas, porque, realmente, el plugin nos servirá así, tal cual, en gran cantidad de ocasiones y las opciones no son el objetivo que persigo aquí.

TODO BIEN, PERO NO FUNCIONA

O tal vez sí. Si lo pruebas, verás que, en ocasiones, cuando introduzcas modificaciones en el archivo sass, el css se compila bien, pero el minificado no siempre se actualiza. Y, lo que es peor. No tienes modo de saber si se ha actualizado o no, a menos que sea inspeccionando visualmente todo el código. Es una tarea ardua, que se presta a errores, y que nos hace perder tiempo. Para ese resultado no necesitaríamos contar con un gestor de tareas. Pero ¿por qué ocurre esto? y, más aún. ¿Por qué ocurre «a veces», y en otras ocasiones no sucede?.

Para responder a esto debemos saber cómo funciona gulp. Cuando se le encarga más de una tarea (cómo en este caso), gulp no espera a terminar la primera para iniciar la segunda. En lugar de eso, ejecuta las tareas «en paralelo». Es lo que en determinados entornos de programación se conoce como ejecución multihilo. Para los que estéis más familiarizados con entornos gráficos, las tareas se ejecutan simultáneamente es distintos «segundos planos». Esto quiere decir que es muy fácil que, al invocarse las tareas, ocurra lo siguiente:

  • Se inicia la primera tarea (en nuestro ejemplo, sass-compile).
  • Se inicia la segunda tarea (en nuestro ejemplo, minifiy-css). Sin embargo, la primera tarea aún no ha concluido, por lo que no tenemos el archivo css actualizado o, simplemente, no lo tenemos). Esto significa que la tarea de minificación no da el resultado deseado.
  • Se finaliza la segunda tarea, aunque no hemos obtenido el minificado deseado.
  • Se finaliza la primera tarea. Ya tenemos el css pero, como la segunda tarea ya se ha llevado a cabo, no se minifica la nueva versión.

LA SOLUCIÓN AL PROBLEMA

La solución a este problema es forzar a gulp a que ejecute las tareas encomendadas «en serie», es decir, que no inicie una hasta haber acabado la anterior, en lugar de «en paralelo». Para ello tenemos que contar con otro plugin, diseñado, específicamente, para modificar la forma de ejecución a una secuencia. Se llama run-sequence y, al igual que todos los plugins, debemos instalarlo en la raíz de nuestro proyecto, así:

npm install --save-dev run-sequence

A continuación, debemos modificar nuestro fichero gulpfile.js para que cargue este plugin en un objeto de gulp (como hacemos con todos los plugins) y para que use el modo de ejecución en secuencia. El resultado es el siguiente (presta especial atención a las líneas resaltadas, con sus comentarios):

CONCLUYENDO

Lo que hemos visto en este artículo es importante. Y, sin embargo, ¿cuando usar o no usar run-sequence? Bien. Cuando tengas varias tareas independientes, que no tengan que trabajar con los resultados de las anteriores, no lo emplearás. Sin embargo cuando (como en este caso), una tarea dependa del resultado de otra, deberás emplear este plugin. Como siempre, en este enlace tienes los archivos de ejemplo. Te los dejo sin los plugins ni el gulp, para que te ejercites haciendo tú mismo las instalaciones pertinentes (revisa los primeros artículos de esta serie, si tienes dudas al respecto). Si quieres leer más sobre el plugin que acabamos de conocer, puedes visitar este enlace.

   

Deja un comentario