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 gulp.watch('./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) {
   gutil.log(error.message);
   if (isFatal(level)) {
      process.exit(1);
   }
}

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

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

    // For all files in the stream, apply the replacement.
    return eventStream.map(function(file, 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*")
        .pipe(tsNameof())
        .pipe(tsProject())
        .pipe(gulp.dest(config.aliasify.src))
        .on('error', onError);
});

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

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

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

gulp.task('watch', function(callback) {
    return gulp.watch('./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)
      .pipe(jshint())
      .pipe(jshint.reporter('default'));
  });

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

Enjoy !

Leave a Reply

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

WordPress.com Logo

You are commenting using your WordPress.com 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.