简体   繁体   中英

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.

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM