No se si conocéis GulpJS pero voy a intentar hacer una breve introducción a está librería, que, para los no lo conozcan se podría decir que es un gestor de tareas similar a Grunt. Esta basado en NodeJS, pero básicamente no tienes porque tocar “nada” de node para trabajar con gulp, simplemente tener instalado node y npm. Lo que si tienes que tener son conocimientos de javascript, aunque mínimos, no hay nada del otro mundo en un script de gulp.

GulpJS nos permite gestionar fácilmente las tareas que debemos realizar a la hora de pasar nuestro proyecto del estado de desarrollo al estado de producción, como por ejemplo minificación de css, renombrado de ficheros, compresión de javascript, e incluso nos permite hacer watching (monitorizar) los archivos o directorios que le indiquemos para que al cambiar algo de estos ejecute las tareas que le asignamos de manera automática. Pero esto no es todo, hay muchos módulos que proveen a gulp de funcionalidades realmente útiles, seguro que encuentras alguna que haga exactamente lo que buscas, y sino es así, siempre podrás hacerla tu!.

Por ejemplo, yo actualmente lo estoy usando en el proyecto de una webapp, donde monitoriza la carpeta donde tengo mis módulos javascript y mis ficheros LESS, si detecta un cambio en alguno de los ficheros javascript ejecuta la tarea de comprimir todos los módulos en un solo fichero y moverlo al directorio del proyecto donde está la versión de producción, igual pasa con los ficheros less, si cambio alguno automaticamente compila todos mis ficheros a un solo fichero css y lo mueve a producción; lo mejor de todo esto es que ocurre realmente rápido, casi imperceptible, hago un cambio, refresco la web y el cambio ya está ahí. Entonces… ¿Empezamos?.

Instalando Gulp

Dando por hecho que tienes instalado en tu sistema node y npm vamos a abrir un terminal y instalar gulp:

sudo npm install -g gulp

A continuación vamos a crear el fichero package.json de tu proyecto, para ellos disponemos de dos formas, la primera y más sencilla es poner en la terminal desde el directorio de tu proyecto:

npm init

El programa te irá haciendo una serie de preguntas, las cuales mayormente podrás dejar en blanco o poner lo que el mismo terminal te sugiere, la otra opción es creando tu mismo el fichero a mano, que ha de contener algo como esto:

{
    "name" : "nombre-de-mi-proyecto",
    "version": "0.0.0"
}

Una vez que lo tengamos creado instalamos gulp como dependencia de desarrollo de nuestro proyecto:

npm install --save-dev gulp

Si ahora miras el contenido de tu package.json verás que se ha añadido algo como esto:

"devDependencies": {
    "gulp": "^3.8.6"
}

Básicamente no solo hemos instalado gulp en el proyecto sino que se ha quedado registrado para que la próxima vez que tengas que hacer una instalación del proyecto baste con un simple:

npm install

Eso instalará nuestro proyecto con todas sus devDependencies en el futuro.

Creando nuestras tareas

Ha llegado el momento de crear nuestras primeras tareas basadas en gulp, para ello creamos un fichero en el directorio de nuestro proyecto llamado gulpfile.js. Este script será quien contenga todas las instrucciones de las tareas que queremos ejecutar en nuestro proyecto. Pero antes deberemos de instalar los modulos que nos hacen falta.

Por ejemplo, queremos unificar y comprimir dos ficheros javascript, para este caso podríamos usar el modulo gulp-uglifyjs:

npm install --save-dev gulp-uglifyjs

Ahora vamos a editar el fichero gulpfile.js, primero que nada, llamamos a los modulos gulp y gulp-uglifiyjs:

var gulp = require('gulp'), 
uglify = require('gulp-uglify');

Ahora, definimos una tarea:

gulp.task('scripts', function(){ 
    console.log('it works!'); 
});

Guardamos el script y nos dirigimos nuevamente a la terminal para poner:

gulp scripts

Que nos mostrará algo como esto:

[15:45:14] Using gulpfile ~/demo/gulpfile.js
[15:45:14] Starting 'scripts'...
it's works!
[15:45:14] Finished 'scripts' after 78 μs

Fácil ¿verdad?, vamos entonces a hacer algo productivo con el modulo uglifyjs que hemos instalado, volvemos a la definición de nuestra tarea a indicarle que ficheros ha de usar, para ello usaremos gulp.src(), al cual le podemos pasar un string o un array con varios strings en su interior, en nuestro caso vamos a pasarle un string simple con un directorio:

var myScripts = 'src/**/*.js'; //Directorio que contiene nuestros scripts 
gulp.task('scripts', function(){ 
    return gulp.src(myScripts); 
});

Pero esto por si solo no hace nada, debemos encadenarle las acciones que ha de realizar con estos ficheros:

var myScripts = 'src/**/*.js'; 
gulp.task('scripts', function(){ 
    return gulp.src(myScripts) 
        .pipe(uglify('main.min.js')) //comprime a main.min.js
        .pipe(gulp.dest('./dist')); //Destino del nuevo fichero en el directorio ./dist 
});

Con esto le estamos indicando a gulp que coja cualquier fichero javascript que se encuentre bajo el directorio src y lo comprima en un solo fichero llamado main.min.js en el directorio ./dist de nuestra aplicación.

Pero, ¿que pasa si necesitamos comprimirlos en orden?, puede darse el caso de que debamos incluir nuestros módulos javascript en cierto orden debido a las dependencias que tienen, para ese caso simplemente tenemos que cambiar en gulp.src() el string que contiene el directorio, a un array con todos los scripts ordenados:

var myScripts = [ 'src/uno.js', 'src/dos.js' ];

Volvemos a la terminal, ejecutamos gulp scripts y aparecerá nuestro script listo para producción en el directorio ./dist.

Muy bien, con esto tenemos definida una tarea simple, pero se nos puede hacer pesado estar ejecutando gulp scripts a cada cambio que realizamos, así que vamos a crear una tarea que monitorize nuestras scripts y automáticamente ejecute la tarea scripts.

Creamos una nueva tarea llamada watch (o como quieras llamarla), le pasamos los ficheros o directorio que ha de monitorizar, y un array con las tareas que ha de llevar a cabo cuando ocurra algún cambio:

gulp.task('watch', function(){ 
    gulp.watch(myScripts, ['scripts']); 
});

Ahora desde terminal, en vez de ejecutar gulp scripts, ejecutaríamos gulp watch, y así cada vez que hiciéramos una modificación a uno de nuestros ficheros javascript se ejecutaría de manera transparente para nosotros la tarea scripts. Si tuvieras más tareas definidas que quisieras ejecutar cuando se detecta un cambio simplemente tendrías que añadirlas al array que le pasamos como segundo parámetros a gulp.watch en el orden que quieras que se ejecuten. También puede darse el caso de que quieras hacer watch de diferentes directorios y que ejecuten diferentes tareas, entonces simplemente añade otro gulp.watch a la tarea:

gulp.task('watch', function(){ 
    gulp.watch(myScripts, ['scripts']);
    gulp.watch('miOtroDirectorio',['miOtraTarea']); 
});

Como ya dije hay muchos módulos de diversas funcionalidades, cualquier cosa que se pueda automatizar seguro que tiene su modulo correspondiente, pero normalmente los módulos o librerías de gulp suelen ser bastante específicos en su función, esto quiere decir que un modulo que comprime quizás no haga renombrado de ficheros, y en ese caso tendrás que encadenar diferentes módulos dentro de la misma tarea, pongamos como ejemplo un compilador LESS, cumple su función compilando, pero no nos permite cambiar el nombre al css resultante, así que vamos a instalar en esta ocasión dos dependencias para hacer esta tarea, gulp-less y gulp-rename:

npm install --save-dev gulp-less gulp-rename

Como de costumbre los añadimos a nuestro fichero gulpfile:

var gulp = require('gulp'), 
    uglify = require('gulp-uglifyjs'), 
    less = require('gulp-less'), 
    rename = require('gulp-rename');

Y creamos la tarea correspondiente, encadenando una detrás de otras las acciones que ha de hacer nuestra tarea:

gulp.task('css', function(){ 
    return gulp.src('src/main.less') 
        .pipe(less()) //Compilamos 
        .pipe(rename('compiled-style.css')) //Renombramos
        .pipe(gulp.dest('./dist')); //Indicamos destino 
});

Imaginando que tenemos un archivo llamado main.less en el directorio ./src, al ejecutar en la terminal gulp css compilaría este less a css, lo renombraría a compiled-style.css y lo ubicaría en ./dist, si elimináramos la linea que incluye el rename el fichero resultante se llamaría main.css. Como ves puedes encadenar todas las acciones que te hagan falta, por ejemplo en este caso podríamos añadir también una modulo que minificara el fichero resultante, pero a estas alturas seguro que ya sabrás hacerlo tu mismo.

Todo esto está muy bien, pero se hace algo pesado ir ejecutando las tareas una a una mediante gulp nombreTarea, así que lo vamos a definir dentro de una tarea llamada default, así tan solo debemos ejecutar gulp en la terminal y se ejecutarán todas las tareas y si una de las tareas es watch pues se quedará observando:

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

Con esto hacemos que al poner simplemente gulp en la terminal se ejecute primero la tarea scripts, luego css y por ultimo watch, y de esta forma nos despreocupemos por estar ejecutando nosotros todo por separado.

Espero que esta pequeña introducción sea de utilidad, he dejado disponible el código en Github por si alguien quiere echarle un ojo. Investigad en la pagina de plugins que funcionalidades existen, seguro que alguna os sorprende, y si queréis dejar en los comentarios que usos le das tu a gulp o cualquier duda o sugerencia, será bien recibida!.