Renewing the grunt & livereload magic
A while ago, I wrote an article explaining how to use grunt and livereload to spare you refreshing your page every time you changed your HTML, CSS or javascipt. The grunt-livereload
plugin it used has gone deprecated, but the "magic" achived by it can still be attained. Let's see how to do it!
It's the same...
As in the previous article, we'll set up grunt to:
- launch a server to host your project's file (helps inject the Javascript needed for livereload to work);
- open the browser to your project (optional, but saves a little time);
- and most importantly, reload the page when you update the
index.html
page.
As in the previous article, we'll keep things simple. The project will have just an index.html
file (content of your choosing, just make sure it has a <body>
tag). And as in the previous article, you'll need to have Grunt JS on your machine. This means you'll need to install NodeJS and NPM too.
... but different
What differs from the first article is the list of packages we'll be using. Out goes grunt-livereload
, and in comes grunt-watch
(which will replace grunt-regarde
as well). Without grunt-livereload
, we also need something to inject the Javascript that reloads the page. This is why we'll replace grunt-contrib-connect
by grunt-express
which has an option just for this. To recap, we'll use:
grunt-express
, to serve the files and inject the livereload javascript;grunt-open
, to open the browser;grunt-contrib-watch
, to monitor the changes on the files and notify the livereload server.
This leads to the following package.json
file at the root of the project:
We can now install the packages running npm install
from a command line opened in the folder of the project. Once it's done, we're ready to dive in the Grunt configuration :)
Serving and receiving
Before we look into livereload, let's get rid of the logistic parts: launching a server and opening the browser automatically. The Grunt configuration is close to the one in the previous article, as `grunt-express` and `grunt-contrib-connect` have similar options (at least for what we're doing). This gives us the following Gruntfile.js
file (to place at the root of your project):
With this configuration, typing grunt server
in your command line (from the folder of the project, of course) will start a server on port 9000 and open https://localhost:9000 so you can access your project.
The reloading magic
Livereload works by relaying notifications that files changed to a bit of javascript on your page that will refresh accordingly (hmmm... might have just killed the magic there :P). This means:
- something needs to tell livereload when the file changes: that's the role of the
grunt-contrib-watch
plugin (it'll start livereload too) - you 'll need the livereload javascript in your page. That's where
grunt-express
comes handy.
Both tasks make it really easy to use livereload, providing a livereload
option. Set it to true
or to the port you want the livereload service to run (is it necessary to remind to use the same port for both options in this case ;)), and you're good to go.
And here is our final Gruntfile! Note the new watch configuration, the livereload
option that appeared in the express
config and the watch
task replacing express-keepalive
:
With the grunt server
task up, if you modify (and save) your index.html
file, your browser now reloads the page automatically. Magic! You can, of course, monitor more than one file with watch
, but I'll let the tasks documentation explain it.
Note: If you run the task on Ubuntu (maybe on other linux distributions too) and encounter a watch ENOSPC
error when running the task, you might want to look at this Github comment.
Note: It seems grunt-express
offers a watch
option to monitor file changes and trigger livereload. This would make the Gruntfile a bit lighter. I prefer having a separate grunt-contrib-watch
task, though. I often need it to monitor files for other purposes (YUIDoc, LESS…). It keeps concerns separated too: grunt-express
serves the files, grunt-contrib-watch
monitors them. This makes it easier to find back where to tweak things, I feel. But it's just personal preference in the end :)
Wrapping it up
grunt-contrib-livereload
is deprecated, but livereload still integrates nicely with Grunt. Even better, the other plugins play well with it, which leads to a much leaner configuration. All is left for me is to thank Chandler Van De Water for letting me now the old plugin was deprecated, and let you enjoy the livereload magic.