Javascript Build System Showdown

Created by Josh Bavari / @jbavari

What this talk is about

  • Understanding issues facing web development
  • Understanding issues facing Nodejs development
  • General derp issues facing Javascript development
  • Solutions for solving above issues

First off - why?

  • You write a lot of Javascript
  • You want to concat/minify assets
  • You want to remove unused CSS
  • You NEED to eliminate (boring) manual tasks
  • You want to lint, test & deploy code
  • You want browser to auto-refresh when you modify files

Second, a story

  • First began mobile Phonegap app on iOS / Android - early 2012
  • Purely HTML/Javascript with some native code
  • Build/release cycle was rough
  • Processes - manual. Not fun & tons of errors

Then, Evolution!

  • Began to seek out better tools, processes, & methodologies
  • Started with basic shell scripts to orchestrate
  • Found Grunt, began to automate boring mundane tasks, lint code, run tests, compile sass, & deploy code

Data & errors arent cheap

  • Preprocess items - LESS/SASS/CoffeeScript
  • Lint code, Run tests
  • Minify assets - HTML/CSS/JS/Images
  • Deploy to CDN / Staging / Prod

Definition: build system

  • Build system = series of task exec in order
  • Javascript tools call themselves task runners
  • Let build system == task runners

Put up or shut up

Demo time!

Your reaction

You're using a build system now

  • Visual Studio (MSBuild)
  • Apache Ant
  • GNU Make
  • Ruby Make (Rake)

Prereqs

  • Node
  • npm
  • package.json - specifying packages

Current Javascript build tools

Why so many?

Think the systems all being tools in a toolshed. Each tool is used differently. Some focused on strictly atomic tasks. Others focused on one pass through. No tool is wrong, just different approaches.

Maturity of projects

  • Brunch - Jan 2011, very mature
  • Grunt.js - Mar 2012, very mature
  • Gulp.js - ~ Aug 2013, relatively mature
  • Broccoli - Feb 2014, still in beta

Community Support

  • Grunt has the most popularity
  • Gulp is the newer kid on the block. Picking up popularity
  • Brunch, fairly new, plenty of plugins & skeletons
  • Broccoli - in beta, have plugins available

Grunt / Gulp interoperability

Grunt has a plugin to run Gulp tasks, and Gulp has a plugin to run Grunt tasks.

Which tool for the task at hand?

Each tool has strengths and weaknesses. Your job will be to identify which tool may be best suited for your needs.

Grunt.js

Getting started


//Install grunt command line tools
npm install -g grunt-cli
//Specify plugins by saving to package.json file
npm install grunt-contrib-uglify --save-dev 
npm install grunt-contrib-concat --save-dev
						

Gruntfile Configuration


grunt.initConfig({
   our_file_list: ['./src/js/{Models,Controllers}/*.js', './src/js/index.js'], 
   uglify: {
      build: {
          src: 'js/reveal.js',
          dest: 'js/reveal.min.js'
      },
      all: {
         files: {
            'js/compiled/file.js': '<%= our_file_list %>',
         }
      }
   },
   concat: {
      dist: {
         src: ['js/reveal.min.js', 'js/compiled/file.js'],
         dest: 'dist/built.js',
      },
   }
});
						

Plugins via package.json


{
  "name": "my-project-name",
  "version": "0.1.0",
  "devDependencies": {
    "grunt": "~0.4.5",
    "grunt-contrib-jshint": "~0.10.0",
    "grunt-contrib-nodeunit": "~0.3.3",
    "grunt-contrib-uglify": "~0.4.0"
  }
}
						

Command Line Usage


//Run all uglify targets
grunt uglify
//Execute uglify, but only the all target
grunt uglify:all

						

Grunt.js - strengths

  • Tons of plugins available
  • Easy to configure individual tasks
  • Easy to use with existing projects
  • Very flexible - allows custom tasks to be written
  • Comes pre-packaged in some generators/scaffolding

Grunt.js - weaknesses

  • Plugins do multiple things
  • Headache of temp files/folders
  • Not one solid control flow
  • Configuration can get lengthy - 500+ lines
  • Very lengthy & vast API

Grunt.js - annoyances

  • Tons and tons of temp files & tasks to clean up
  • Can get pretty slow when tasks increase

Gulp.js

Getting started


//Install grunt command line tools
npm install -g gulp
//Specify plugins by saving to package.json file
npm install --save-dev gulp-uglify
npm install --save-dev gulp-concat
					

gulpfile Configuration


var gulp = require('gulp');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
gulp.task('scripts', function() {
   // Minify and copy all JavaScript (except vendor scripts)
   return gulp.src(paths.scripts)
      .pipe(uglify())
      .pipe(concat('all.min.js'))
      .pipe(gulp.dest('build/js'));
});
					

Command Line Usage


//Run all uglify targets
gulp scripts
					

Gulp.js - strengths

  • Provides node streams - no need for tmp files/folders
  • Tons of plugins available
  • Gulpfile is code, not config
  • Plugins do ONE thing
  • Only has 5 functions to learn!

Gulp.js - weaknesses

  • Can be daunting to learn streams
  • Sometimes setting up src/dest can be tricky (use base)

Gulp.js - annoyances

Havent used long enough to form any

Brunch

The first build system widely used and available. Uses skeletons (like scaffolding) to create app directory structure.

Getting started


//Create new skeleton of angular app
brunch new https://github.com/scotch/angular-brunch-seed myapp
//Install bower packages (css/js/etc)
bower install
//tell Brunch to watch your project and incrementally rebuild it when source files are changed
brunch watch --server
//builds a project for distribution. By default it enables minification
brunch build --production
					

Brunch - strengths

  • Easy to set up - use skeleton
  • Introduces conventions for you
  • Simple CLI - only a few commands
  • Commands for dev/staging/production releases

Brunch - weaknesses

  • Not using conventions causes headaches
  • Not easy to set up with existing projects
  • Skeleton set ups not maintained as fast as plugins
  • Not as supported as Grunt/Gulp

Broccoli

Mainly focused on Ember.js apps, and ships with Ember CLI

Broccoli - strengths

  • Trees allow dev to think of assets
  • Provides caching for map files
  • Makes some conventions for you - assets
  • Watching files handled by serve, only rebuilds whats needed

Broccoli - weaknesses

  • No parallelism

Choosing YOUR build strategy

  • If you need tons of plugins, stick with Grunt or Gulp
  • If you need utter speed, go with Gulp
  • If you want conventions, go with Brunch
  • If you're an Ember fan, go with Broccoli (tied into Ember CLI)

References