Automatización de tareas con Gulp

Si eres un/a desarrollador/a web front-end y no estás familiarizado/a con Gulp, dejame decirte que estás malgastando una gran cantidad de tu “tiempo humano” en tareas que tienes que realizar y vigilar a lo largo del desarrollo de un proyecto, que no hacen más que limitar tu productividad, y que podrías estar automatizando. Entre ellas se encuentran:

  • Configurar el proyecto en algún preprocesador de Sass (y no olvidar abrirlo y darle a “Start” cada vez que retomas el trabajo).
  • Atender la compatibilidad con navegadores antiguos en la escritura tanto de CSS como de JS, lo cual implica, para el primero, el uso de prefijos proveedores (vendor prefixes) o de alguna biblioteca, como Prefix free de la gran Lea Verou, y, para lo segundo, algún compilador en la vena de Babel, que nos genere un archivo que pueda ser comprendido por viejos navegadores que no tengan implementados los estándares de ES6.
  • Recargar el navegador para ver los cambios aplicados; esto suena demasiado obvio, pero te aseguro que después de pasar de la ventana del editor de código a la del navegador, presionar F5 y luego volver, durante todo un día de trabajo, agradecerás lo que te presentaré más adelante en este artículo.
  • Por último, al momento de entrar en producción, minificar todo tu código con fines de optimización.

Expresado así no parece mucho, pero si te dijera que con un solo script reutilizable puedes realizar todas estas tareas, juntas o por separado, ejecutando un comando, y no se te ponen los ojos vidriosos, tal vez es que no estás poniendo atención, o quizás vengas de Webpack, solo en ese caso estarías perdonado/a; de eso ya hablaré en otra ocasión. De momento, centrémonos, porque te quiero hablar acerca de…

La misión de Gulp

Gulp es esa bebida que te ayuda a bajar un bocado grande y pesado. Comúnmente se conoce a este tipo de herramientas como “task runner” (“corredor de tareas”), pero yo prefiero llamarlo un automatizador de tareas, uno pensado especialmente para las necesidades del front.

No solo se pueden ejecutar tareas con una simple instrucción de línea de comandos, Gulp también cuenta con un método que permite escuchar cambios en cualquier archivo y procesarlo mediante un sinfín de plugins que se encuentran disponibles.

 

Instalación

Pero, ¿cómo se implementa Gulp exactamente? Lo primero que debes saber, es que Gulp.js es un módulo de Node.js y, por lo tanto, si no lo tienes instalado en tu sistema, deberás hacerlo. Si no estás familiarizado con Node.js en profundidad no es un problema, pero sí deberías, al menos, conocer su gestor de paquetes: NPM.

A los fines de este artículo, te enseñaré cómo instalar Node.js y Gulp.js; ya queda en tí investigar más acerca de Node.

 

NodeJS

Lo primero será ir a la web oficial y descargar la versión LTS (botón verde de la izquierda). Recibirás un archivo .tar.xz que puedes descomprimir donde más te guste. La carpeta resultante lleva un nombre así:

node-v8.x.x-linux-x64

Entra en la carpeta y abre una terminal allí, o abre una terminal nueva y navega hasta adentro de la misma, como prefieras. Una vez allí, ejecuta los siguientes comandos:

sudo cp -r */ /usr/
sudo apt update

Esto instalará Node y, por consiguiente, su ya mencionado gestor de paquetes, el cual utilizarás para instalar Gulp. Lo primero será hacerlo disponible globalmente, mediante…

sudo npm i gulp -g

Con eso ya tienes lo necesario para empezar a utilizar Gulp y su amplio arsenal de plugins en cualquiera de tus futuros proyectos.

 

Implementación

Con Gulp disponible en todo tu sistema, lo único que debes a continuación es ir a la carpeta de tu proyecto, inicializarlo para así cargar los módulos básicos de node y generar el archivo package.json; fundamental a la hora de replicar el mismo en otro ordenador. Acto seguido, instalar Gulp guardándolo en dependencias de desarrollo, para que luego al exportar el proyecto las mismas se conserven. En resumen, sería ejecutar lo siguiente…

npm init -y
npm i --save-dev gulp

Como se supone que tu eres el dueño de la carpeta, no es necesario que ejecutes estos comandos con ‘sudo’.

Ahora bien, para poder programar tus tareas necesitarás hacerlo dentro de un archivo que se deberá nombrar gulpfile.js  y deberá ir en la raíz de tu proyecto (ambas cosas son obligatorias). Aprovechando que estás en la terminal y parado sobre la carpeta de tu proyecto…

touch gulpfile.js

Dentro de este archivo, importaremos Gulp para poder acceder a sus propiedades y métodos…

const gulp = require('gulp');

Con esto, técnicamente, ya tenemos Gulp integrado en nuestro proyecto. Todo muy lindo pero…

 

¿Qué puedo exactamente hacer con Gulp y cómo?

Gulp, como ya mencioné, cuenta con una cantidad abrumadora de plugins para satisfacer casi cualquier requerimiento de front. En este artículo cubriré los que yo considero esenciales, aquellos que utilizo en todos mis proyectos como condición sine qua non, pero déjame decirte que cada vez que quieras buscar uno siempre puedes ir a la web oficial de npm y en la barra de búsqueda escribir ‘gulp-‘ seguido de una palabra o criterio; por ejemplo ‘gulp-sass’. También puedes directamente ingresar una oración, y el motor hurgará en la descripción de los paquetes para mostrarte resultados relacionados.

Compilar Sass

Primero, en la terminal…

npm i --save-dev gulp-sass

…y luego, dentro de gulpfile.js

const sass = require('gulp-sass');
gulp.task('sass', function() {
 return gulp.src('src/scss/*.scss')
 .pipe(sass({ outputStyle: 'expanded' })) // acepta 'nested', 'compact', 'expanded' o 'compressed'
 .pipe(gulp.dest('src/css'))
});

¿Qué hemos hecho realmente? Bien…

  • En la primera línea requerimos el módulo el cual, como ven, debe ser literalmente el nombre del plugin, y lo guardamos dentro de una constante (si quieres usar una variable, es igual, solo ten cuidado de no modificar su valor en otro lugar del archivo).
  • En la segunda línea es donde creamos la tarea y le damos un nombre (el que tú quieras), que disparará una función anónima que es la que hará toda la magia. A mí me gusta ser explícito, por eso la he llamado ‘sass’.
  • Luego, en la línea 3 definimos la ruta donde vamos a ir a buscar nuestros archivos .scss de Sass, (aquí deberías insertar la tuya). Con el asterisco, por supuesto, le estamos diciendo que busque cualquier archivo con la extensión .scss
  • De aquí en más, a través de las “pipes” o “tuberías”, iremos encadenando los procesos que manejaran el/los archivos y les darán el tratamiento adecuado. En este caso, decirle que lo pase por el preprocesador de Sass, para finalmente colocar el archivo .css resultante en una carpeta de destino (la que tú definas)

Para todas las tareas el procedimiento es prácticamente el mismo por lo que no volveré a repetir la explicación, para los que siguen solo dejaré el código.

Autoprefixer

Para aplicar los prefijos de proveedores de CSS donde sea necesario.

npm i --save-dev gulp-autoprefixer
const autoprefixer = require('gulp-autoprefixer');



gulp.task('prefixCSS', function() {
 gulp.src('src/css/*.css')
 .pipe(autoprefixer({
  browsers: ['last 2 versions'], // Podemos definir el soporte que queremos dar. Para más opciones ver: https://github.com/ai/browserslist
  cascade: false
 }))
 .pipe(gulp.dest('src/css'))
});

 

Babel

Si quieres escribir en EcmaScript 6 sin preocuparte por la compatibilidad con navegadores antiguos, Babel se ocupará de ello por tí.

npm i --save-dev gulp-babel
const babel = require('gulp-babel');



gulp.task('babel', function() {
 return gulp.src('src/js/main.js') // o el nombre de tu archivo JS principal
 .pipe(babel({
  presets: ['env'],
 }))
 .pipe(gulp.dest('src/js'));
});

 

Imagemin

Muy útil para optimizar tus imágenes para la web, sobre todo PNG.

npm i --save-dev gulp-imagemin
const imagemin = require('gulp-imagemin');



gulp.task('imagemin', function() {
 gulp.src('src/img/*.{jpg, png, gif, svg'})
 .pipe(imagemin())
 .pipe(gulp.dest('dist/images')) // carpeta de salida
});

Browsersync

Aunque no se trata de un plugin de Gulp, si no de un módulo de Node.js, se puede integrar facilmente. Configurándolo, recargará el sitio automáticamente cada vez que guardes cambios en tus archivos. Además, permite sincronizar la navegación en varios dispositivos, de manera que puedes interactuar con tu sitio y observar su comportamiento en cada uno de ellos. Por ejemplo, si haces scroll verás como se produce el mismo en todos los dispositivos al simultáneo. Hace un tiempo subí una demostración en mi Instagram:

Para ello…

npm i --save-dev browser-sync
const browserSync = require('browser-sync').create();



// Si es un proyecto sin back end
gulp.task('browser-sync', function() {
 browserSync.init({
  server: {
   baseDir: './'
  }
 });
});



// Si es un proyecto con back-end
gulp.task('browser-sync', function() {
 browserSync.init({
  proxy: 'localhost:8080'
 });
});

Para el primer caso, el puerto donde podrás ver el sitio será por defecto el 3000, es decir que para navegar el sitio en cualquier otro dispositivo que esté conectado a la red, tienes que ingresar la IP del ordenador que está corriendo Gulp con BrowserSync, más el puerto, en la barra del navegador, de la siguiente forma. Por ej:

192.168.0.1:3000

Así ya habrás sincronizado los navegadores entre dispositivos. Para saber la IP de tu ordenador, puedes valerte del comando ifconfig (si ahora no entiendes esto, googleando un mínimo, lo conseguirás, no es nada complicado). Para el segundo caso, es decir si tu proyecto ejecuta instrucciones del lado del servidor, el puerto lo puedes cambiar según dónde tengas montado tu web server.

 

Casi terminamos

Aun falta algo importante. Habrás notado que ahora te quedaste con un montón de tareas que, si quieres correrlas, tienes que hacerlo una por una y varias veces, en algunos casos. El próximo último paso es crear una tarea que se encargue de ejecutar todas las anteriores de una vez y que, además, esté a la escucha de cambios, que dispararán cada una cuando estos ocurran (ej. Sass y Babel). A esta tarea yo la llamaré ‘dev’, ya que todas las que engloba son, mayoritariamente, de desarrollo. Tal vez más adelante, de acuerdo a la acogida que tenga este artículo, les recomendaré algunos plugins y cómo configurar Gulp para producción.

Por ahora, hagamos lo siguiente:




gulp.task('dev', ['browser-sync', 'babel', 'sass', 'prefixCSS'], function() {
  gulp.watch('src/**/*.css', ['prefixCSS']);
  gulp.watch('src/**/*.scss', ['sass']);
  gulp.watch('src/**/*.js', ['babel']).on('change', browserSync.reload);
  gulp.watch('src/*.html').on('change', browserSync.reload);
});



Aquí lo que hicimos fue crear una tarea ‘dev’ que ejecute en cadena todas las demás tareas que creamos antes (nótese que van en forma de array), y, por último se dispara una función que hace lo siguiente, respectivamente:

  • Escucha cambios en los archivos .css y aplica los prefijos de proveedores
  • Escucha cambios en los archivos .scss y compila
  • Escucha cambios en los archivos .js y aplica Babel; además, recarga el navegador con BrowserSync
  • Escucha cambios en los archivos .html y recarga navegador

Solo falta una cosa más. Querrás también que el navegador recargue los estilos cada vez que se ejecute la compilación de Sass, ya que, así como están las cosas, BrowserSync solo se disparará cuando se actualice el HTML o el JS. Pues bien, para ello solo hay que añadir una línea de código en la tarea ‘sass’:




gulp.task('sass', function() {
  return gulp.src('src/scss/*.scss')
  .pipe(sass({ outputStyle: 'expanded' }))
  .pipe(gulp.dest('src/css'))
  .pipe(browserSync.stream()); // ESTA ES LA LÍNEA QUE HAY QUE AGREGAR
});



 

Ahora sí

Ya tenemos automatizada una parte importante de nuestro workflow front-end para la fase de desarrollo. Al principio, puede parecer algo complicado, pero creeme, cualquier cosa nueva que se aprende en la vida es complicada hasta que deja de serlo. Puedes releer la totalidad o las partes que necesites de este artículo hasta que te quede todo claro, pero lo más importante es que lo pongas en práctica y empieces a investigar la herramienta y sus posibilidades por tu cuenta. También puedes hacerme cualquier consulta en la caja de comentarios aquí debajo. En esta ocasión te invito además también a seguirme en Instagram y Twitter. Un saludo y hasta la próxima, Linuxterrestres.

Imágen de portada hecha en GIMP por Adrián Benavente

Leave a Reply