In the first part of this series, we learned how to make a build pipeline using Gulp. There was a missing part though. Whenever you’re doing React Development, you’ll want to be sure to watch file changes for your application to reload automatically.

The trick is to define a new ‘run & watch’ task:

gulp.task('runandwatch', ['run', 'watch']);

Nothing very fancy here, we launch the run task followed by the watch task.

Let’s define the watch task:

gulp.task('watch', function(callback) {
    return'./src/**/*.ts*', ['run']);

The watch task will re-run the run task. So we’re in an infinite loop of run/watch/run and so on.

That’s it. We have a build pipeline that pre process typescript files, transpiles them, then post process the resulting Javacript files for aliasing.

The complete gulp file follows:

var gulp = require('gulp');

var eventStream = require('event-stream');
var joinPath = require('path.join');
var clean = require('gulp-clean');
var webpack = require('webpack-stream');

var ts = require("gulp-typescript");
var tsNameof = require("ts-nameof");
// To use tsconfig.json
var tsProject = ts.createProject('tsconfig.json');

var gutil = require('gulp-util');
var argv = require('yargs').argv;
var runSequence = require('run-sequence');

var jshint = require('gulp-jshint');

function getBuildPath() {
    return './out/';

var config = {
    aliasify: {
        src: './.temp/' + argv.platform,
        dest: getBuildPath() + 'js/',
        aliases: (argv.platform === 'web') ?
        // Web Aliases
            'AppAlertAndPrompt': './AlertAndPromptWeb'
        } :
        // Native Aliases
            'AppAlertAndPrompt': './AlertAndPromptNative'

// Command line option:
//  --fatal=[warning|error|off]
var fatalLevel = require('yargs').argv.fatal;

var ERROR_LEVELS = ['error', 'warning'];

// Return true if the given level is equal to or more severe than
// the configured fatality error level.
// If the fatalLevel is 'off', then this will always return false.
// Defaults the fatalLevel to 'error'.
function isFatal(level) {
   return ERROR_LEVELS.indexOf(level) <= ERROR_LEVELS.indexOf(fatalLevel || 'error');

// Handle an error based on its severity level.
// Log all levels, and exit the process for fatal levels.
function handleError(level, error) {
   if (isFatal(level)) {

// Convenience handler for error-level errors.
function onError(error) {, 'error', error);}
// Convenience handler for warning-level errors.
function onWarning(error) {, 'warning', error);}

function aliasify(aliases) {
    var reqPattern = new RegExp(/require\(['"]([^'"]+)['"]\)/g);

    // For all files in the stream, apply the replacement.
    return, done) {
        if (!file.isNull()) {
            var fileContent = file.contents.toString();
            if (reqPattern.test(fileContent)) {
                file.contents = new Buffer(fileContent.replace(reqPattern, function(req, oldPath) {
                    if (!aliases[oldPath]) {
                        return req;

                    return "require('" + aliases[oldPath] + "')";

        done(null, file);

gulp.task('typescript', function() {
    return gulp.src("src/**/*.ts*")
        .on('error', onError);

gulp.task('apply-aliases', function() {
    return gulp.src(joinPath(config.aliasify.src, '**/*.js'))
        .on('error', onError);

gulp.task('clean-dest', function() {
    return gulp.src(config.aliasify.dest, {read: false})

gulp.task('clean-src', function() {
    return gulp.src(config.aliasify.src, {read: false})

gulp.task('watch', function(callback) {
    return'./src/**/*.ts*', ['run']);

gulp.task('run', function(callback) {
    runSequence(['clean-dest', 'clean-src'], 'typescript', 'apply-aliases', 'clean-src', 'lint', 'bundle', callback);

gulp.task('runandwatch', ['run', 'watch']);

gulp.task('lint', function() {
    return gulp.src(config.aliasify.dest)

gulp.task('bundle', function() {
    if (argv.platform === 'web')
        return gulp.src(joinPath(config.aliasify.dest, 'index.js'))
            .pipe(webpack( require('./_____webpack.config.js') ))
        return gutil.noop();

Enjoy !

Leave a Reply

Please log in using one of these methods to post your comment: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.