Una de las características de un desarrollador con la que más me identifico es que somos perezosos.
Esto no quiere decir que no nos guste trabajar.
Lo que quiere decir es que no nos gusta hacer la misma cosa más de una vez. Así que al proceso de modificar/guardar/compilar/recargar, tan común en el desarrollo de aplicaciones Web, le buscamos constantemente solución.
Entonces, para evitar hacer labores repetitivas no hay mejor solución que automatizar. Y en la actualidad encontramos que soluciones de automatización para el desarrollo de aplicaciones Web y móviles, hay muchas:
- Scripts de bash
- Scripts de CMD (en Windows)
- Gard (Ruby)
- Grunt (node)
- Gulp
- Etc.
Todas estas herramientas lo que hacen es ejecutar tareas automáticamente para ciertos eventos. Como cuando se crea un archivo en una ruta específica, se modifica un archivo, se cumple un tiempo de inactividad, se ejecuta un comando específico, etc.
De todas estas herramientas, Gulp y Grunt se destacan por su flexibilidad y versatilidad siendo Grunt la herramienta preferida por muchos.
La gran diferencia de Gulp con Grunt radica en que mientras Grunt usa un archivo de configuración y plugins específicos de Grunt, Gulp usa un script de node.js donde se pueden usar módulos exclusivos de Gulp o módulos corrientes de npm.
Es decir, mientras uno debe configurar Grunt, Gulp se debe programar.
Antes que digas que es mejor configurar que programar, déjame decirte cuáles son las ventajas de Gulp sobre Grunt.
- Se pueden usar prácticamente todos los módulos de npm.
- Al ser un programa, puede hacer cosas muy complicadas como condicionales y loops.
- Puede extender su funcionalidad más fácil con módulos de node.
- Puedo segmentar mi configuración (que en realidad es una aplicación).
Grunt sigue siendo una alternativa fantástica de automatización, pero mi opinión es que Gulp es más poderoso y flexible que Grunt.
Descargar Gulp
La instalación de Gulp no puede ser más sencilla si ya estás familiarizado con la instalación de módulos de npm.
Entonces, debemos instalar el comando Gulp de manera que lo podamos acceder desde cualquier lugar de nuestro equipo:
npm install -g gulp
Para los nuevos: -g significa que se instalará un nuevo comando en el equipo y que +éste será accesible globalmente.
package.json
Como toda aplicación de node, es necesario crear el archivo pakacke.json en donde especificaremos todos los módulos de [npm] que vamos a usar. Entonces ejecutamos:
npm init
Esto iniciará el wizard de npm donde especificaremos datos básicos de nuestro proyecto
name: (tutorial-gulp) version: (1.0.0) 0.0.1 description: Un sitio usando gulp entry point: (index.js) test command: git repository: keywords: author: Mario Yepes license: (ISC)
Esto genera el archivo package.json con el siguiente contenido
{ "name": "tutorial-gulp", "version": "0.0.1", "description": "Un sitio usando gulp", "main": "index.js", "scripts": { "test": "echo "Error: no test specified" && exit 1" }, "author": "Mario Yepes", "license": "ISC" }
Hasta aquí tenemos lo siguiente:
- Acceso al comando Gulp de manera global.
- Una carpeta donde crearemos nuestro aplicativo en PHP, Ruby, node o lo que sea que estemos usando.
- El archivo package.json donde describimos nuestro proyecto.
Inicio de configuración de Gulp
Aunque ya tenemos el comando gulp instalado de manera global, es necesario instalar el módulo en el directorio del proyecto y así crear nuestra aplicación de automatización.
npm install --save-dev gulp
Le pasamos la bandera –save-dev ya que este módulo solo lo necesitamos para el proceso de desarrollo, más no para la ejecución del programa.
Si la aplicación a desarrollar está escrita en otro lenguaje como PHP, Ruby, Python, etc. Entonces no es necesario pasar esta bandera ya que los módulos instalados nunca serán usados en producción.
El archivo gulpfile.js
El aplicativo o centro de la automatización de [Gulp] es el archivo gulpfile.js y es en éste donde especificaremos las tareas o tasks que queremos ejecutar automáticamente cada vez que guardamos un archivo y creemos una nueva imagen o se cumpla cierto período.
A modo de ejemplo, ejecutamos el comando gulp sin tener este archivo previamente creado.

Adicionalmente, gulpfile.js debe tener algún tipo de tarea especificada.
A continuación se muestra que pasa si ejecutamos gulp teniendo un archivo gulpfile.js, pero sin tareas

Un gulpfile.js básico
Creemos entonces la tarea de gulp más sencilla: La tarea Hola Mundo
// Archivo gulpfile.json var gulp = require('gulp'); gulp.task('default', function() { console.log('Hola Mundo!!!'); });
En este caso, si no tenemos errores, en la terminal veremos:

Agregando plugins.
La mayor parte del trabajo de Gulp lo hacen los plugins y módulos de npm que instalamos.
De por sí los módulos de gulp son muchos, para la fecha que se escribió este artículo habían 1424. Es por esto que existe el buscador de plugins http://gulpjs.com/plugins/.
Empecemos entonces instalando el plugin gulp-uglify que se encargará de comprimir todo nuestro código javascript en un solo archivo y de manera casi ilegible.

Para instalarlo solo debemos ejecutar en la terminal el siguiente comando (muy parecido a la instalación del módulo de gulp)
npm install --save-dev gulp-uglify
Luego de unos segundos tendremos el módulo de gulp-uglify instalado y el archivo package.json actualizado.
Ahora lo que hay que hacer es modificar el archivo gulpfile.js agregando una tarea que se encargue de uglificar los archivos javascript que creemos.
// Archivo gulpfile.json var gulp = require('gulp'), uglify = require('gulp-uglify'); gulp.task('default', function() { gulp.src('js/*.js') .pipe(uglify()) .pipe(gulp.dest('min_js')); });
Como se puede ver estamos asumiendo que nuestros archivos javascript residirán en el subdirectorio js.
Expliquemos un poco lo que hicimos:
- En la sección de “require” agregamos el nuevo módulo gulp-uglify
- Modificamos la tarea default para incluir el proceso de uglify
- Usamos la función de node pipe() para ejecutar varias sub-tareas de manera encadenada, es decir, que la salida de una se convierta en la entrada de la siguiente. De esta manera tenemos que…
- Buscar los archivos con extensión js en el subdirectorio js
- Estos archivos los pasa por uglify
- La salida del proceso de uglify la guarda en el subdirectorio min_js
Organización de tareas
Antes de agregar más tareas, hagamos un poco de limpieza de código: Saquemos todo el proceso de uglify de default y hagamos que default ejecute una nueva tarea que llamaremos uglify
// Archivo gulpfile.json var gulp = require('gulp'), uglify = require('gulp-uglify'); gulp.task('default', ['uglify']); gulp.task('uglify', function() { gulp.src('js/*.js') .pipe(uglify()) .pipe(gulp.dest('min_js')); });
Como se puede ver, tenemos aquí dos tareas: default y uglify y la primera lo que hace es ejecutar la segunda.
Si queremos solo ejecutar la tarea de uglify entonces debemos digitar en la consola el siguiente comando
gulp uglify
Con esto nos estamos asegurando que si hay más tareas en gulpfile.js solo la de uglify será ejecutada.
Watch.
Esta es una de las tareas más populares en Gulp la cual consiste en realizar una serie de acciones cuando se crea o modifica un archivo.
Entonces, crearemos una nueva tarea llamada watch, en la cual usaremos la tarea nativa de gulp llamada watch. Esto quiere decir que no tenemos que instalar nuevos plugins para obtener esta funcionalidad.
// Archivo gulpfile.json var gulp = require('gulp'), uglify = require('gulp-uglify'); gulp.task('default', ['uglify', 'watch']); gulp.task('uglify', function() { gulp.src('js/*.js') .pipe(uglify()) .pipe(gulp.dest('min_js')); }); gulp.task('watch', function() { gulp.watch('js/**/*.js', ['uglify']); });
Aquí realizamos dos cambios:
- Creamos la tarea watch especificando que cuando cambie un archivo en el subdirectorio js con extensión js se debe ejecutar la tarea uglify
- Se modificó la tarea default para que ejecute uglify y watch
NOTA Las tareas de gulp corren en paralelo y no de forma secuencial, por lo que hay que tener cuidado con tareas que necesitan que otra se haya terminado
SASS
Tengo que admitirlo, adoro Sass. Tener variables en CSS es un sueño hecho realidad. Pero SASS se debe convertir a CSS antes de usarlo en una página Web y Gulp tiene un plugin para esto.
Entonces instalamos el plugin de SASS a CSS con el siguiente comando.
npm install --save-dev gulp-sass
Con el plugin instalado, agregamos una nueva tarea, agregamos un nuevo tipo de archivos a la tarea watch y le decimos a default que debe ejecutar una tarea más
// Archivo gulpfile.json var gulp = require('gulp'), uglify = require('gulp-uglify'), sass = require('gulp-sass'); gulp.task('default', ['uglify', 'scss', 'watch']); gulp.task('uglify', function() { gulp.src('js/**/*.js') .pipe(uglify()) .pipe(gulp.dest('min_js')); }); gulp.task('scss', function() { gulp.src('scss/**/*.scss') .pipe(sass()) .pipe(gulp.dest('css')); }); gulp.task('watch', function() { gulp.watch('js/**/*.js', ['uglify']); gulp.watch('scss/**/*.scss', ['scss']); });
Si creamos un archivo de prueba podemos verificar que la nueva tarea de gulp está funcionando:
// Archivo scss/test.scss $bg-color: '#ff00ff'; body { background: $bg-color; }
Genera el archivo
body { background: '#ff00ff'; }
Plumber
Algo en lo que Gulp es muy poco versátil es en manejo de errores. Muchas veces simplemente dice que hay un error y para de funcionar.
En el siguiente ejemplo agregamos un error a test.scss
// Archivo scss/test.scss $bg-color: '#ff00ff' // falta ; al final body { background: $bg-color; }

Afortunadamente la comunidad creó el plugin Plumber que se encarga de evitar que gulp watch deje de funcionar en caso de un error.
Entonces instalemos plumber
npm install --save-dev gulp-plumber
Y agreguemos plumber a las tareas que queremos que no dejen de funcionar ante un error
// Archivo gulpfile.json var gulp = require('gulp'), uglify = require('gulp-uglify'), sass = require('gulp-sass'), plumber = require('gulp-plumber'); gulp.task('default', ['uglify', 'scss', 'watch']); gulp.task('uglify', function() { gulp.src('js/**/*.js') .pipe(plumber()) .pipe(uglify()) .pipe(gulp.dest('min_js')); }); gulp.task('scss', function() { gulp.src('scss/**/*.scss') .pipe(plumber()) .pipe(sass()) .pipe(gulp.dest('css')); }); gulp.task('watch', function() { gulp.watch('js/**/*.js', ['uglify']); gulp.watch('scss/**/*.scss', ['scss']); });
Como podemos ver a continuación, si hay un error, gulp continúa trabajando.

Disminuir tamaño de imágenes
Otra de las tareas que podemos realizar con Gulp es hacer que las imágenes de nuestro sitio Web tengan menor tamaño. Para esto se usa el plugin imagemin.
Entonces, instalamos el plugin y modificamos gulpfile.js para agregar una tarea que minimice nuestras imágenes.
npm install --save-dev gulp-imagemin// Archivo gulpfile.json var gulp = require('gulp'), uglify = require('gulp-uglify'), sass = require('gulp-sass'), plumber = require('gulp-plumber'), imagemin = require('gulp-imagemin'); gulp.task('default', ['uglify', 'scss', 'imagemin', 'watch']); gulp.task('uglify', function() { gulp.src('js/**/*.js') .pipe(plumber()) .pipe(uglify()) .pipe(gulp.dest('min_js')); }); gulp.task('scss', function() { gulp.src('scss/**/*.scss') .pipe(plumber()) .pipe(sass()) .pipe(gulp.dest('css')); }); gulp.task('imagemin', function() { gulp.src('img/**/*.{jpg,jpeg,png,gif}') .pipe(plumber()) .pipe(imagemin()) .pipe(gulp.dest('img_min')); }); gulp.task('watch', function() { gulp.watch('js/**/*.js', ['uglify']); gulp.watch('scss/**/*.scss', ['scss']); gulp.watch('img/**/*.{jpg,jpeg,png,gif}', ['imagemin']); });

Require-dir.
Guardar las tareas (tasks) en archivos por separado.
var requireDir = require('require-dir'); // Require all tasks in gulp/tasks, including subfolders requireDir('./gulp/tasks', { recurse: true });
Run-sequence
Como habíamos dicho al principio de este artículo, Gulp corre las tareas en paralelo y esto no es siempre deseable, sobretodo cuando una tarea depende de otra.
Por ejemplo cuando queremos primero concatenar varios archivos .js en uno solo y luego comprimirlos.
En este caso, el plugin run-sequence se encarga de que las tareas corran en secuencia y no en paralelo.
Un ejemplo de cómo funciona es el siguiente.
var runSequence = require('run-sequence'); // importamos el plugin gulp.task('default', function() { runSequence( ['minify-css', 'minify-js'], // estas dos corren en paralelo de primero 'replace-build-ids', // luego esta 'create-backup-zip', // luego esta ['copy:fonts', 'copy:images'] // por último estas dos en paralelo ); });
Conclusión
Como se puede ver, Gulp es extremadamente poderoso a la hora de automatizar tareas y esto no solo hace que ahorremos tiempo sino que nuestro trabajo sea menos tedioso.
¿Necesitas automatizar tareas? Contacta a Dazzet.
Si crees que hay algo que haga gulp y que no esté en este artículo, por favor deja un comentario
Actualizado: martes, 11 de abril de 2023