Using GulpJS, Browserify, and Watch for AngularJS Development

Hold on Cowboy

This blog post is pretty old. Be careful with the information you find in here. It's likely dead, dying, or wildly inaccurate.

That’s quite a mouth full, but in a nutshell we just want to develop AngularJS and have [Gulp]() watch our files and recompile them when they change.

var gulp       = require('gulp'),
    _          = require('lodash'),
    fs         = require('fs'),
    nodemon    = require('gulp-nodemon'),
    ini        = require('ini'),
    config     = ini.parse(fs.readFileSync('./.env', 'utf-8')),
    concat     = require('gulp-concat'),
    uglify     = require('gulp-uglify'),
    htmlMin    = require('gulp-minify-html'),
    browserify = require('gulp-browserify'),
    clean      = require('gulp-clean'),
    watch      = require('gulp-watch'),
    ngHtml2Js  = require('gulp-ng-html2js');

gulp.task('default', function(){
  // Update process.env with our .env values
  _.assign(process.env, config);
  nodemon({
    script: 'index.js',
    options: '-e html,js -w lib'
  });
});

gulp.task('clean', function(cb) {
  gulp.src('./build')
    .pipe(clean({
      force: true
    }).on('end', function() {
      cb();
    }));
});

gulp.task('ng', ['clean'], function() {
  buildTemplates("./public/src/**/*.tpl.html", "partials.min.js", "./build/js/");
});

gulp.task('copy', ['clean'], function() {
  copyIndex();
});

gulp.task('bundle', ['clean'], function() {
  buildAppJs('public/src/app.js', './build/js');
});

gulp.task('build', ['ng', 'copy', 'bundle']);

gulp.task('watch', ['build'], function() {
  gulp.src('public/**')
    .pipe(watch(function(files) {
      buildAppJs('public/src/app.js', './build/js');
      buildTemplates("./public/src/**/*.tpl.html", "partials.min.js", "./build/js/");
      copyIndex();
    }));
});

function copyIndex() {
  return gulp.src('public/index.html')
    .pipe(htmlMin({
      empty: true,
      spare: true,
      quotes: true
    }))
    .pipe(gulp.dest('./build/'));
}

function buildAppJs(files, outfile) {
  return gulp.src(files)
    .pipe(browserify())
    .pipe(uglify())
    .pipe(gulp.dest(outfile));
}

function buildTemplates(src, file, dest) {
  return gulp.src(src)
      .pipe(htmlMin({
        empty: true,
        spare: true,
        quotes: true
      }))
      .pipe(ngHtml2Js({
          prefix: "/"
      }))
      .pipe(concat(file))
      .pipe(uglify())
      .pipe(gulp.dest(dest));
}

But what does it all mean ??? 

Glad you asked. Let me break some of the essential parts down.

We are going to run gulp watch. That will set the task watch in motion. As you see it’s going to run the build command first. This build command will run ng, copy, and bundle, which all of them will wait until the the clean task runs.

  1. clean empties the ./build folder
  2. ng creates builds the AngularJS templates (stores them in the templateCache)
  3. copy this just copies the index.html into ./build
  4. bundle this runs browserify on our AngularJS files and spits it out to ./build
  5. watch will first run all the above to set things up, then it will watch all the files under public/** for changes. When it sees a change it will run the tasks again (except for clean)

I should note that my default task just runs nodemon

Did this help you out? It took me a few days to piece together all this information together, I hope this saves you some time (who knows, maybe the future me will be thankful I wrote this down). Let me know your thoughts. shanestillwell@gmail.com