There's been a new name making some buzz in world of JS task runners lately: Gulp. Curious, I've given it a quick go to see how hard it would be to get the minimal express & livereload setup I did with Grunt.
What's that Gulp thing
A bit of setup
So let's get started on this Gulp + Express + Livereload configuration. We'll split this in two steps and start with the Express setup. Then we'll add the livereload configuration.
But first of all, you'll need the
gulp CLI installed on your system. A quick
npm call will sort that (don't forget to
sudo if your system requires it, I always do :s):
npm install -g gulp.
gulp command is available, let's bootstrap our project. As a starting point, we'll use a simple folder containing:
index.htmlfile (content is up to you, just make sure it has a
package.jsonfile to store the project's dependencies (
npm initwill help you scaffold one),
- a local install of
gulpin your project (
npm install gulpfrom your project's folder, no
Gulpfile.jsfile to store Gulp configuration:
If you don't want to leave your Gulpfile empty and already start playing with Gulp, you could fill it with the following code that provides a default "Hello world"-ish Gulp task. To run your "build", just go
gulp in your command line. As the command provides no specific task, it will run whatever
To get Express to host our project's file, we'll need a new dependency in the project. Let's just
npm install express --save-dev
You'll notice we're installing the actual
express package and not a specific plugin for Gulp. Gulp encourages to use the libraries as is when the task has nothing to do with manipulating streams, like popping up a web server, launching tests... This makes running Express with Gulp pretty much the same as when creating a standalone Express app. This gives us the following Gulp configuration to start up Express.
gulp command now pops up a server, and if you point your browser to http://localhost:4000, you should see the content of you
The express startup could also have been a task of its own. We'd just needed to wrap it in a
gulp.task call. Then we could have called it via
gulp.run inside the default task. It all depends on wether you need to launch express on its own or just use it when running other tasks.
Adding some livereload magic
As for starting up an Express server, starting up a livereload server doesn't have much to do with manipulating streams. This means no need for a specific Gulp plugin, we'll just use
tiny-lr. We'll also need the
npm install tiny-lr connect-livereload --save-dev
This makes us 3 steps away from having livereload set up. First on, starting up livereload! As with Express, we'll wrap tinylr bootstrap in a specific function (don't forget to call it in the
default task ;) ).
gulp now starts up two services: Express on port 4000 and tinylr on port 35729. If you go to http://localhost:35729, you'll get a warm JSON welcome from
Next step is to get express to inject the liverload JS snippet in the HTML it serves. You can skip this if you're using a browser plugin to communicate with the livereload server. This is the job of the
connect-livereload middleware. We just need to load it before the the
static() configuration, which makes the
startExpress() function look like this:
The pages served by Express now have a small bit of JS injected just before their
body closing tag. This will make them react to the livereload updates. All that's left now is sending livereload notification when file changes. Gulp comes in with a built in
watch()method, so let's take advantage of this and make a final update to our Gulpfile:
What about gulp-livereload ?
If you look up on the NPM registry, you'll find a plugin for Gulp called
gulp-livereload. It allows you to send notifications to the liverload server as part of your
pipe() chain. This would make the
notifyLivereload() function a bit more concise:
As we're not doing much with our HTML file in the current Gulpfile, this approach does not bring much besides conciseness. But when processing files more heavily, it saves you from having to watch both the source files and their processed results. You can just pipe to
gulp-livereload once you've gone through, say, LESS processing and CSS minification, instead of monitoring the
.less to trigger the processing, and the
.css files to trigger livereload.
Wrapping it up!
Thanks for staying till the end! Happy Coding ;)