Search code examples
javascriptnode.jsgulpbrowserifynode-streams

How do I emit an event into gulp-tap's parent stream


I'm setting up a gulpfile for bundling multiple JavaScript files into multiple bundles during development.

Since I want to watch this process and not have it exit if there is an error (syntax or something) in one of the files I would need to properly emit an end event to the parent stream.

For handling the multiple files I am using the approach described in the gulp recipes.

But using this and reading the docs on gulp-tap I am unsure how to have it emit the error into the parent stream.

What I am trying to do is the following:

gulp.task('bundle', () => (
    gulp.src(['whatevs/*.js'], { read: false })
        .pipe($.tap((file) => {
            file.contents = browserify( // eslint-disable-line no-param-reassign
                file.path,
                { debug: true, fullPaths: true }
            ).bundle();
        }))
        .on('error', function handleBrowserifyError(err) {
            this.emit('end');
        })
        .pipe(gulp.dest('bundles/'))
));

I can see the error if I would pass a callback to the bundle() call, but I do not have the slightest clue how to get it back into the parent stream.


Solution

  • I managed to do it like this:

    gulp.task('bundle', () => {
        const scriptStream = gulp.src(['whatevs/*.js'], { read: false })
            .pipe($.tap((file) => {
                file.contents = browserify( // eslint-disable-line no-param-reassign
                    file.path,
                    { debug: true, fullPaths: true }
                )
                .bundle()
                .on('error', () => scriptStream.emit('end'));
            }))
            .on('error', Function.prototype) // prevents crashing
            .pipe(gulp.dest('bundles/'));
        return scriptStream
    });