Compile TypeScript and Package with Browserify in a Single Gulp Task

OK - the topic of packaging your js with browserify using Gulp has been done to death. However, integrating TypeScript into this workflow can be a little bit of a challenge because browserify doesn't take a regular gulp file stream as input.

tldr;

Just want to copy and paste some code and get on with your life? Here's the task that I ended up writing:

var gulp = require('gulp');
var buffer = require('vinyl-buffer');
var source = require('vinyl-source-stream');
var browserify = require('browserify');
var tsify = require('tsify');

gulp.task('build:ts', function () {
    return browserify()
        .add('./my-app/App.ts')
        .plugin(tsify)
        .bundle()
        .on('error', function (error) { console.error(error.toString()); })
        .pipe(source('bundle.js'))
        .pipe(buffer())
        .pipe(gulp.dest('./ReviewForm/'));
});

This method relies on a few plugins: tsify, vinyl-buffer, and vinyl-source-stream.

Explanation

If you're keen-eyed (or didn't install the dependencies after you copy and pasted the code) you'll spot the three things of interest in this gulp task: tsify, buffer(), and source().

tsify

The TypeScript gets compiled in this recipe using a browserify transform. Transforms allow you to hook into the browserify packaging process, in this case to compile TypeScript. Luckily, there exists a pre-written TypeScript transform for browserify called tsify.

vinyl-source-stream

Gulp can perform operations on special types of node streams called vinyl file streams. Essentially, vinyl is a format for describing files (more info here). However, browserify().bundle() returns a regular text-based node stream. vinyl-source-stream takes one of these conventional node text streams and returns a vinyl file stream (that gulp can deal with).

vinyl-buffer

Technically, in this task, vinyl-buffer isn't needed. However, if you'd like to pipe your browserified stream into another pipe such as uglify() you'll need to run it through this vinyl-buffer first. Otherwise, you'll find yourself at the mercy of an unhandled error.