Automatización de tareas de frontend usando Gulp.js

Como desarrollador Frontend, hay ciertas tareas que se terminan volviendo repetitivas durante el desarrollo, como compilar el CSS desde un pre-procesador, concatenar archivos o minificarlos. Es hasta el ambiente de producción en donde realizamos estas dos ultimas tareas.

Gracias a herramientas como Gulp.js y Grunt.js ahora es posible automatizar todas estas tareas repetitivas e inicializarlas con un único comando en la terminal. En este tutorial les voy a explicar como usar una de estas herramientas, Gulp.js.

Descargar e instalar Gulp.js

Lo primero que necesitamos hacer para empezar a usar Gulp.js es descargarlo e instalarlo, para esto necesitamos tener Node.js instalado, si no lo tienen pueden ir al sitio, descargarlo e instalarlo. Una vez tengan Node.js simplemente abren la consola y escriben el comando para instalar Gulp.js de forma global.

sudo npm i -g gulp

Luego de que lo tengan instalado de forma global necesitan instalarlo en cada proyecto donde lo vayan a usar, para eso simplemente van desde la consola a la carpeta del proyecto usando el comando:

npm i -D gulp

El -D es para que lo agregue como dependencia de desarrollo en el archivo package.json del proyecto. Es lo mismo que --save-dev.

Instalar plugins

Lo siguiente es buscar los plugins necesarios para nuestro proyecto, para eso pueden ir al sitio de Gulp.js y en la sección de plugins tienen la lista completa con un buscador.

O pueden ir directamente a NPM y buscar ahí el plugin agregando la palabra gulp a su búsqueda.

Para este ejemplo vamos a compilar del pre-procesador LESS a CSS, además de minificar el CSS resultante y por último que si se cambian los archivos de LESS vuelva a compilar.

Para esto buscamos y descargamos los plugins gulp-less, gulp-minify-css y gulp-watch, podemos instalarlos en nuestro proyecto con el comando:

npm i -D gulp-less gulp-minify-css gulp-watch

Con esto ya están descargados en la carpeta node_modules del proyecto y agregados como dependencia de desarrollo a nuestro package.json.

Armar las tareas de Gulp.js

Ahora viene lo más importante, armar las tareas que queremos ejecutar, para esto necesitamos crear un archivo gulpfile.js en la raíz de nuestro proyecto (donde esté el package.json), en este archivo lo primero que vamos a hacer es cargar Gulp.js y nuestros plugins, para eso agregamos estas líneas:

var gulp = require("gulp");
var less = require("gulp-less");
var minifyCSS = require("gulp-minify-css");
var watch = require("gulp-watch");

Ya importados los módulos necesarios podemos escribir nuestras tareas. Las tareas en gulp se definen con el método task que posee gulp y que recibe el nombre de la tarea y una función a ejecutar.

gulp.task("css", function() {
  // acá vamos a poner nuestra tarea
});

Dentro de nuestra tarea lo primero es indicar cuales son los archivos sobre los que vamos a trabajar, para esto usamos otro método de gulp llamado src que recibe o un string con la ruta relativa al archivo o un array con muchos archivos, estas rutas pueden hacer referencia a una carpeta entera usando * en lugar del nombre de un archivo. En nuestro caso solo apuntamos a nuestro archivo principal.

gulp.task("css", function() {
  gulp.src("./less/main.less");
});

Ahora necesitamos empezar a ejecutar nuestros plugins, para eso necesitamos decir a Gulp.js que luego de obtener el archivo main.less le pase el contenido a nuestros plugins, esto se hace con el método pipe que recibe como parámetro la ejecución de una función, en nuestro caso uno de nuestros plugins.

gulp.task("css", function() {
  gulp
    .src("./less/main.less")
    .pipe(
      less({
        paths: __dirname + "/less",
        filename: "main.less",
        ru: true
      })
    ) // 1
    .pipe(minifyCSS()); // 2
});

En el punto 1 compilamos nuestro LESS a CSS, el objeto que le pasamos como parámetro le indica la ruta donde encontrar todos nuestros archivos de LESS, el nombre de nuestro archivo principal y por último que use rutas relativas para los @import que usemos en nuestros archivos, de esta forma podemos trabajar con múltiples archivos LESS y Gulp.js los va a compilar a un único CSS. El punto 2 recibe el CSS compilado en el punto 1 y lo minifica, simple.

Por último para terminar nuestra tarea necesitamos indicarlo donde guardar el archivo final que generamos, esto es con otro método de Gulp.js llamado dest, este método recibe como único parámetro un string con la ruta donde vamos a guardar los archivos finales.

gulp.task('css', function () {
   gulp.src('./less/main.less')
   .pipe(less({
      paths: __dirname + '/less',
      filename: 'main.less',
      ru: true
   }))
   .pipe(minifyCSS())
   .pipe(gulp.dest('./css');
});

Se agrega dentro de una pipe para poder recibir el archivo que minificado que devuelve minifyCSS.

Ahora que tenemos nuestra tarea lista la podemos ejecutar desde la terminal con el comando:

gulp css

Cuando se termine de ejecutar la tarea (mientras más pipe agregues más tarda) vamos a tener un archivo main.css en la carpeta css ubicada en la raíz de nuestro proyecto.

Ahora nos falta poder vigilar todos los cambios de los archivos de la carpeta less y volver a ejecutar automáticamente la tarea css, para eso creamos otra tarea llamada watch y programamos la tarea de esta forma:

gulp.task("watch", function() {
  gulp.watch(["./less/**/*.less"], ["css"]);
});

Esta vez no hicimos la tarea como antes, esto es porque el plugin gulp-watch agrega un método watch a gulp en lugar de funcionar como una tarea normal que se usa con pipe, por eso simplemente le decimos que se fije en la carpeta less cualquier archivo .less (*.less) ubicado tanto en esta carpeta como en otras subcarpetas (**) y si alguno cambia ejecute la tarea css. Los parámetros pueden no estar en un array, pero si los pasas en un array podes ejecutar múltiples tareas o escuchar varias rutas.

Ahora para poder ejecutar esta tarea tenemos que usar el comando

gulp watch

Con esto ya estaría escuchando los cambios, sin embargo actualmente tendríamos que ejecutar dos comandos para hacer que todo funcione perfectamente, primero compilar una vez el CSS y luego escuchar los cambios.

Como esto es molesto también podemos automatizarlo, para eso creamos una nueva tarea y la llamamos default, a esta tarea no le pasamos una función como hicimos antes, sino que le pasamos un array con cada una de las tareas que queremos que se ejecuten, en nuestro caso css y watch.

gulp.task("default", ["css", "watch"]);

Ahora simplemente usamos el comando:

gulp

Y con esto estamos ejecutando una vez cada tarea (al no indicar el nombre de la tarea Gulp.js trata de ejecutar la tarea con el nombre default, si no existe da error), así que primero compila el CSS y luego se queda escuchando los cambios, ya luego es la tarea watch la que se encarga de volver a ejecutar la tarea css cada vez que sea necesarios.

Conclusión

Al principio puede resultar algo raro estar automatizando estas tareas, pero luego de acostumbrarse pasa a ser algo casi imprescindible en cada proyecto que realicemos, y con la gran cantidad de plugins que existen para Gulp.js se pueden automatizar una cantidad enorme de cosas ya sea compilar Stylus, CoffeeScript, concatenar archivos de JS, minificarlos, ejecutar pruebas unitarias e incluso es posible iniciar un servidor HTTP para probar el sitio.

Los invito a probar Gulp ó si no les convence intentar con Grunt.js, otro automatizador de tareas. Sin duda alguna vale mucho la pena incorporar estas herramientas en nuestro ambiente de trabajo para ayudarnos a poder dedicar más tiempo a escribir código y menos a realizar todas estas tareas repetitivas.