Como crear tareas gulp de manera dinámica.

Una de las cosas que más me está gustando de ser programador es que con el tiempo ganas experiencia y empiezas a ver que casi todo el código que escribes se puede abstraer usando métodos más genéricos. Hace poco me pasó mientras estaba creando unas tareas con gulp.

Os explicaré un poco lo que estaba haciendo y así podréis ver el big picture. Durante el año pasado he creado un par de paquetes npm, son utilidades para ser usadas en una página web. Ya sabía como iban a funcionar con plain javascript y jQuery pero no tenía muy seguro como usarlos en React y Angular, es por eso que hice una pequeña webApp donde poder probar estos paquetes ya sea en React, Angular o cualquier otro frontend framework.

Una vez estaba desarrollando esta webApp ya me di cuenta de que para React y Angular estaba usando las mismas gulp tasks pero lo único que cambiada era el string que bien era react o angular.

Para ello vamos a usar el process de Node.js.

El objecto process es una global que proporciona información acerca y control sobre el actual proceso de Node.js. Como global que es, siempre está disponible en las aplicaciones Node.js sin la necesidad de usar require()

process.argv

La propiedad process.argv devuelve un array que contiene los argumentos pasados a la línea de comando cuando una aplicación Node.js es iniciada. El primer elemento del array es process.execPath y el segundo elemento es la ruta del archivo Javascript que se está ejecutando. El resto de elementos serán los adicionales argumentos pasados a la línea de comandos.

Teniendo process.argv en mente si en nuestro archivo package.json tenemos los siguientes scripts:

"scripts": {
    "react": "gulp build-react",
    "angular": "gulp build-angular"    
  },

Cuando vayamos a nuestro terminal y escribamos npm run react, process.argv devolvería lo siguiente:

 [ '/usr/local/bin/node',
  '/Users/byverdu/Projects/playground/node_modules/.bin/gulp',
  'build-react' ]

Si quisieremos usar la tarea angular, al usar npm run angular el último elemento de process.argv sería 'build-angular'.

Ahora que ya sabemos como encontrar que tipo de npm script estamos ejecutando tan solo tenemos que crear las tareas gulp que sean completamente genéricas.

Por ejemplo, si queremos usar browserify para crear nuestros bundles deberíamos configurar la tarea de la siguiente manera:

export default function browserifySetup( task ) {  
  gulp.task( task, () => {
    const b = browserify({
      entries: `./src/${task}/app.js`,
      debug: true,
      transform: [babelify]
    });

    return b.bundle()
      .pipe( source( 'bundle.js' ))
      .pipe( buffer())
      .pipe( sourcemaps.init({ loadMaps: true }))
      .on( 'error', gutil.log )
      .pipe( sourcemaps.write( './' ))
      .pipe( gulp.dest( `./src/${task}/` ))
      .pipe( notify({ message: `${task} completed` }));
  });
}

Nuestro archivo gulpfile.js debería lucir de la siguiente manera:

import gulp from 'gulp';  
import watchSetup from './build/tasks/watch';  
import browserSyncSetup from './build/tasks/browser-sync';  
import browserifySetup from './build/tasks/browserify';

require( 'require-dir' )( './build/tasks' );

const taskName = process.argv.pop().split( '-' ).pop();  
watchSetup( taskName );  
browserSyncSetup( taskName );  
browserifySetup( taskName );

gulp.task(  
  `build-${taskName}`,
  [`browserSync-${taskName}`, `watch-${taskName}`]
);

Este sería el proyecto https://github.com/byverdu/playground donde lo he puesto en práctica.

Espero que os sirva de ayuda :)

comments powered by Disqus