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:
- Validate your JavaScript using JSHint.
- Concatenate your script into a single file.
- Save the concatenated file as app.js.
- Reload the web browser so you can see the changes.
- Minify the javascript.
- 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.