Šime Vidas
Šime Vidas

Reputation: 186083

Avoiding code repetition when creating multiple bundles with Gulp and Browserify

Given these dependencies:

var browserify = require('gulp-browserify');
var buffer = require('vinyl-buffer');
var maps = require('gulp-sourcemaps');
var uglify = require('gulp-uglify');
var rename = require('gulp-rename');

How can I remove the code repetition in these two tasks:

gulp.watch('source/js/site/*.js', ['build-site-js']);
gulp.watch('source/js/admin/*.js', ['build-admin-js']);

gulp.task('build-site-js', function () {
    return gulp.src('source/js/site/site-client.js') // DIFFERENT
        .pipe(browserify({ debug: true }))
        .pipe(buffer())
        .pipe(rename('bundle.js')) // DIFFERENT
        .pipe(gulp.dest('public/js/'))
        .pipe(maps.init({ loadMaps: true }))
        .pipe(rename({ suffix: '.min' }))
        .pipe(uglify())
        .pipe(maps.write('./'))
        .pipe(gulp.dest('public/js/'))
        .pipe(livereload());
});

gulp.task('build-admin-js', function () {
    return gulp.src('source/js/admin/admin-client.js') // DIFFERENT
        .pipe(browserify({ debug: true }))
        .pipe(buffer())
        .pipe(rename('admin.js')) // DIFFERENT
        .pipe(gulp.dest('public/js/'))
        .pipe(maps.init({ loadMaps: true }))
        .pipe(rename({ suffix: '.min' }))
        .pipe(uglify())
        .pipe(maps.write('./'))
        .pipe(gulp.dest('public/js/'))
        .pipe(livereload());
});

Notice that I’m generating two Browserify bundles using an identical process. The only differences between these two tasks are the names for the source and destination files. (I’ve marked the differences with // DIFFERENT comments.)

Ideally, I’d like to have a single gulp.watch('source/js/**/*.js', ['build-js']);, and then inside the task callback, determine in which directory the change occurred, and set the source and destination file names dynamically.

Upvotes: 1

Views: 233

Answers (2)

Šime Vidas
Šime Vidas

Reputation: 186083

This is the accepted answer. (Stack Overflow doesn’t allow me to accept my own answer until tomorrow. I am not going to set up a reminder on my phone just for this, so in case I forget, consider this the accepted answer.)


This setup works for me:

gulp.watch('source/js/**/*.js', function (options) {
    var dir = options.path.match(/\\js\\(\w+)\\/)[1]; // Windows specific [1]

    gulp.src('source/js/' + dir + '/' + dir + '-client.js')
        .pipe(browserify({ debug: true }))
        .pipe(buffer())
        .pipe(gulp.dest('public/js/'))
        .pipe(maps.init({ loadMaps: true }))
        .pipe(rename({ suffix: '.min' }))
        .pipe(uglify())
        .pipe(maps.write('./'))
        .pipe(gulp.dest('public/js/'))
        .pipe(livereload());
});

// [1] Use path.sep for a portable solution: nodejs.org/api/path.html#path_path_sep

I’m using the object argument of the gulp.watch callback to determine the parent directory of the changed file - either 'site' or 'admin' in my case. Based on that, I dynamically generate the gulp.src input.

To make things simpler, I’ve also removed the renaming part, so the bundles “keep” the name of the file that is the bundle’s entry point.

Upvotes: 1

baao
baao

Reputation: 73281

Just write a function that takes the different args:

function doGulp(src, res) {
   return gulp.src(src) 
    .pipe(browserify({ debug: true }))
    .pipe(buffer())
    .pipe(rename(res)) 
    .pipe(gulp.dest('public/js/'))
    .pipe(maps.init({ loadMaps: true }))
    .pipe(rename({ suffix: '.min' }))
    .pipe(uglify())
    .pipe(maps.write('./'))
    .pipe(gulp.dest('public/js/'))
    .pipe(livereload());
}

and call it in the tasks:

gulp.task('build-admin-js', function () {
  return doGulp('source/js/admin/admin-client.js','admin.js');
});
gulp.task('build-site-js', function () {
   return doGulp('source/js/site/site-client.js','bundle.js');
});

So that your gulpfile becomes:

var browserify = require('gulp-browserify');
var buffer = require('vinyl-buffer');
var maps = require('gulp-sourcemaps');
var uglify = require('gulp-uglify');
var rename = require('gulp-rename');

function doGulp(src, res) {
   return gulp.src(src) 
    .pipe(browserify({ debug: true }))
    .pipe(buffer())
    .pipe(rename(res)) 
    .pipe(gulp.dest('public/js/'))
    .pipe(maps.init({ loadMaps: true }))
    .pipe(rename({ suffix: '.min' }))
    .pipe(uglify())
    .pipe(maps.write('./'))
    .pipe(gulp.dest('public/js/'))
    .pipe(livereload());
}

gulp.watch('source/js/site/*.js', ['build-site-js']);
gulp.watch('source/js/admin/*.js', ['build-admin-js']);
gulp.task('build-admin-js', function () {
  return doGulp('source/js/admin/admin-client.js','admin.js');
});
gulp.task('build-site-js', function () {
   return doGulp('source/js/site/site-client.js','bundle.js');
});

Upvotes: 1

Related Questions