How to create gulp tasks dynamically

During the last year I created a couple of npm packages that were frontend focused. I was sure about how to use them with plain javascript and jQuery but I wasn't 100% sure about how to use them with React and Angular. So I thought to create a webApp where I could test those npm packages for React and Angular and any other frameworks in the future.

Once I was developing this webApp I already realized that I was using the same gulp tasks for both frameworks and the only thing that was changing was the string that was or either react or angular.

To achieve this goal we are going to use process from Node.js.

The process object is a global that provides information about, and control over, the current Node.js process. As a global, it is always available to Node.js applications without using require().


The process.argv property returns an array containing the command line arguments passed when the Node.js process was launched. The first element will be process.execPath. See process.argv0 if access to the original value of argv[0] is needed. The second element will be the path to the JavaScript file being executed. The remaining elements will be any additional command line arguments.

If we have in mind process.argv and in our package.json file we have the following scripts:

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

Once we type npm run react in the terminal, process.argv will have this values:

 [ '/usr/local/bin/node',
  'build-react' ]

Now that we know how to retrieve the arguments passed to the command line we only need to create the gulp tasks in a generic way.

For example, if we are going to use browserify to generate our bundled code we could do something like this:

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` }));

And then in our gulpfile.js file we could do something like this:

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 );

  [`browserSync-${taskName}`, `watch-${taskName}`]

This is the project where I am using this functionality:

comments powered by Disqus