Uncategorized

Using Babel and Browserify with gulp

Summary

Use the through2 npm library to pipe your gulp stream through Browserify, and use the babelify Browserify transformer instead of gulp-babel. Check out the gist

Building with magic

As a developer working primarily in JavaScript, my relationship with build processes can be best described as “hot and cold.” My expected workflow is thus: make a change in my editor, flip over to my browser, see my changes already up on the page without a manual refresh (thanks to LiveReload or something similar).

With that as a baseline, build processes that make me wait (or worse, do things manually!) can quickly become beyond frustrating. On the other side of the spectrum, build processes that maintain the illusion of “instant magic” and make it easier to work with the code itself?

Impressive, very nice.

To that end, Browserify has been a part of my build process for a while now… I’m enamored with the idea of using not just the same language but the exact same codebase on both the client and the server, and letting Browserify do all the heavy lifting of the boilerplate for that seems like an obvious win.

Additionally, I’ve traditionally been a grunt user, but I made the switch to gulp recently. Two reasons for that: first, I like the philosophy of operating on streams instead of files, but mostly, I like that a gulp task is actually code instead of mostly configuration. It mostly comes down to style and personal preference, but there it is. Making Browserify work in gulp was an interesting exercise at first, but it seemed worth it.

Enter Babel

I’ve been excited about some of ES6’s features for a while now: arrow functions, iterators and generators, easier use of classes… these are all awesome. When I’m working on a personal project, I try to make as much use of them as possible, but even Chrome (my browser of choice) doesn’t support the full range yet. So when I hear about Babel (which was named 6to5 at the time), I was instantly on board. It’s a preprocessor that will transpile ES6 to ES5, and according to kangax’s ES6 compatibility table, it’s currently leading in terms of supported feature count. Running a shell command to process everything was of course out of the question, but Babel’s docs have information on using Babel with both gulp and with Browserify.

… erm, that is to say, the docs have information on using Babel with gulp and using Babel with Browserify separately, but trying to get them to play together was not as easy. First, I tried using gulp-babel and piping that to Browserify, but that didn’t work, as Browserify reads the input files itself and didn’t want to play nicely with my stream. Then I tried using vinyl-transform and piping the gulp stream through that and using babelify instead of gulp-babel, but that let me with a frustrating stack trace that would disappear as soon as I stopped trying to preprocess with babel:

[code lang=text]
Error: write after end
at writeAfterEnd (/Users/problematic/dev/node_modules/browserify/node_modules/readable-stream/lib/_stream_writable.js:161:12)
at Labeled.Writable.write (/Users/problematic/dev/node_modules/browserify/node_modules/readable-stream/lib/_stream_writable.js:208:5)
at write (_stream_readable.js:602:24)
at flow (_stream_readable.js:611:7)
at _stream_readable.js:579:7
at process._tickCallback (node.js:442:13)
[/code]

In frustration, after playing with it for a few hours, I opened an issue on the babelify, and within five minutes (!), one of the devs (possibly the head dev, but I’m not that familiar with the development on the project) got back to me.

Looks like it’s due to vinyl-transform. Quick search shows that it’s an issue a lot of people run into when using it, substack/node-browserify#1044. The suggestion here might work.

Mild embarrassment from not finding the same result as his “quick search” aside, I gave it a whirl, and it works great. I now have my files being preprocessed by Browserify and Babel, managed by gulp. Here’s how my gulp task ended up looking:

The code

5 thoughts on “Using Babel and Browserify with gulp

    1. Glad I could help! Looks like you have an answer to your SO question already; is there anything else you need?

      1. nope! I had all the tools to refactor my js code with es6/modules, feels much better now.
        oh and the gif reminded me to watch again american psycho ;)

  1. Wouldn’t this be easier?

    var gulp = require(‘gulp’);
    var browserify = require(‘browserify’);
    var babelify = require(‘babelify’);
    var source = require(‘vinyl-source-stream’);

    gulp.task(‘build’, function() {
    browserify({
    entries: ‘./src/main.js’,
    debug: true
    })
    .transform(babelify)
    .bundle()
    .pipe(source(‘bundle.js’))
    .pipe(gulp.dest(‘./dist’));
    });

    1. Yep! I tried to avoid writing intermediate files to the filesystem, as that’s not really “idiomatic” gulp, but if you’re okay with it, this looks much simpler. Thanks!

Leave a Reply