Need a developer?

LiveReload for Chrome extensions with Gulp

LiveReload is a fantastic feature to add to your development workflow to increase your productivity. The general idea is that when a change occurs to a file that makes up your app, your app is automatically rebuilt and the app restarts itself. This saves you from manually rebuilding and restarting your app each time you make a change and generally makes development much more pleasant.

There are LiveReload implementations available for many languages and frameworks such as tiny-lr which can be used with Gulp for web development. However, I recently found the standard way of using tiny-lr does not work when developing Chrome extensions without a slight change.

To get started, you need to create a gulpfile.js file containing something like the following:

var gulp = require('gulp');
var tinyLr = require('tiny-lr');

gulp.task('watch', function () {
    var liveReload = tinyLr();
    liveReload.listen(35729);
    gulp.watch(['**/*.css', '**/*.html', '**/*.js'], function (watchEvent) {
        console.log(watchEvent);
        liveReload.changed({
            body: {
                files: [watchEvent.path]
            }
        });
    });
});

When you run gulp watch a tiny-lr server is started which will communicate between the Gulp task and your app. The Gulp task then watches the current folder and subfolders for any changes to css, html and js files. If a change is detected, the tiny-lr server is notified.

The next stage in the process when a change is identified is that tiny-lr should instruct your app to restart. To create the link between tiny-lr and your app, you normally include a tiny-lr script at startup in your app using the following snippet:

<script src="http://localhost:35729/livereload.js"></script>

However, due to the increased security restrictions of Chrome extensions, you’ll see this error message on startup:

Refused to load the script 'http://localhost:35729/livereload.js' because it violates the following Content Security Policy directive: "script-src 'self' 'unsafe-eval'".

The problem is you cannot load external JavaScript files without whitelisting secure script locations. However, there’s a simpler alternative.

In the node-modules folder that tiny-lr is installed under, you can find the above tiny-lr script our app was trying to load via tiny-lr’s server in the file node_modules/tiny-lr/node_modules/livereload-js/dist/livereload.js. To work around the external JavaScript loading issue, we can instead load this file directly.

One last piece in the puzzle is the script needs to know the host and port of the tiny-lr server. This information can be set via URL parameters. The working script tag to include in your app is then as follows:

<script src="node_modules/tiny-lr/node_modules/livereload-js/dist/livereload.js?host=localhost&port=35729"></script>

Now whenever you edit a development file, your Chrome extension should automatically reload itself. Happy developing!