Gulp

Gulp is a development automation tool. It allows us to pipe files through a succession of pipline stages. Each stage can transform the files in the pipe.

For example, we might a pipeline to:

  1. Validate your JavaScript using JSHint.
  2. Concatenate your script into a single file.
  3. Save the concatenated file as app.js.
  4. Reload the web browser so you can see the changes.
  5. Minify the javascript.
  6. Save the minified code again as app.min.js.

Gulp streams

Gulp has a concept of streams. A stream is a set of files that can be transformed.

We create a stream using gulp.src, then pipe it through different functions which can transform the stream in a variety of ways. We can optionally pipe our stream back out onto the filesystem at any point using gulp.dest.

We use gulp for:

  • Validation
  • Compilation
  • Concatenation
  • Reformatting
  • Renaming
  • Wrapping content
  • Anything else we can think of…

The Gulpfile

We configure gulp using a file called gulpfile.js. By convention, this lives in our project root. Our gulpfile contains a set of tasks that we would like to automate.

Our gulpfile might be tiny, it might only run jsLint on save, or it might be huge, rebuilding our entire project including HTML, JavaScript, CSS and images.

A simple gulpfile to lint concatenate and save all the JavaScript in a project might look like this:

var gulp = require('gulp'),
hint = require('gulp-jshint'),
concat = require('gulp-concat');
gulp.task('js', function () {
return gulp.src('**/*.js')
.pipe(hint())
.on('error', gutil.log)
.pipe(concat('app.js'))
.pipe(gulp.dest('build'));
});

Gulp modules

We extend the capabilities of Gulp using modules, which are installed using npm. Here are some useful ones:

  • jshint - JavaScript validation
  • sass - CSS precompilation
  • Uglify - JavaScript minification
  • Concat - Script concatenation
  • Autoprefixer - Automatically add vendor prefixes to CSS
  • Header - Adds a header to the file
  • Size - Outputs the size of a minified file

Validating code

A common requirement is to validate our JavaScript. We can do this with a simple Gulp task:

var gulp = require('gulp'),
jshint = require('gulp-jshint');
gulp.task('assets:js', function () {
return gulp.src(components.js)
.pipe(jshint())
.pipe(jshint.reporter('default'))
}

We execute this task with:

gulp assets:js

Automatic execution

We can tell gulp to watch our filesystem for changes, and execute a task whenever a file is modified.

gulp.task('watch', function() {
gulp.watch(components.js, ['assets:js']);

Now we might create a default gulp task:

gulp.task('default', [
'watch'
]);

We can now set our gulp task running simply by typing gulp at a command line.

gulp

Exercise - JSHint

Install Gulp and the gulp-cli using npm. Note that currently gulp has to be installed locally in your project, so we omit the -g flag.

npm install gulp
npm install gulp-cli -g

Test your installation:

gulp --version

Now we're going to set up gulp to validate our javascript.

first install the gulp-jshint dependency

npm install gulp-jshint

Now create a gulpfile containing something like the following:

var gulp = require('gulp'),
jshint = require('gulp-jshint');
gulp.task('js', function () {
return gulp.src('js/**/*.js')
.pipe(jshint())
.pipe(jshint.reporter('default'))
}

Now run gulp js to execute the task:

gulp js

Any errors? You may need to introduce an error to see the effect.

Set up Gulp to automatically validate the code in your node server. When you save the file, it should give you an error if you have made a mistake.

Piping out a stream

We can make transformations to our code right in the stream, and then at any point, pipe it out into a file. We might pipe it out more than once if we want to.

var gulp = require('gulp'),
concat = require('gulp-concat'),
uglify = require('gulp-uglify');
gulp.task('js', function () {
return gulp.src('./js/**/*.js')
.pipe(concat('app.js'))
.pipe(gulp.dest('./build/js'))
.pipe(rename('app.min.js'))
.pipe(uglify())
.pipe(gulp.dest('./build/js'))
});

Exercise - Pipe out

Try to get the above running. Make a gulp task that will concatenate and minify your JavaScript.

Remember you will need to npm install gulp-concat and gulp-uglify.

Now integrate this with the lint exercise above. Make a task that will first lint your code, then concat and minify.

Angular Exercise - ngAnnotate

ngAnnotate is a project that will convert Angular round brace injectors into minification safe square brace injectors.

Here's the gulp task: https://www.npmjs.com/package/gulp-ng-annotate

Try to integrate ngAnnotate into your js build process.

Exercise - Header

You might wish to mark your generated files as such so that future coders don't try to edit them directly. We can use gulp-header for this.

https://www.npmjs.com/package/gulp-header

Use gulp-header to add a header to your concatenated js file, something like this:

"Generated by `gulp js`
// Do not modify
"

Exercise - Validate your gulpfile

Slightly meta this one. Use the gulp-jsonlint package to automatically validate your gulpfile.

comments powered by Disqus