Browsersync with the Rails Asset Pipeline

One of my coworkers said that he really liked Browsersync. One of the features that it offers is live-reloading.

It sounded interesting, but I didn't want to use node/webpack for asset management.

My requirements were

  • Node.js must be a completely optional developer dependency
  • Asset compilation must be manged via Rails sprockets

Prerequisites

The development packages that I used were gulp and browser-sync. I installed each with yarn

yarn init
yarn add --dev gulp
yarn add --dev browser-sync

gulpfile.js

These rules will automatically cause a full browser refresh whenever any asset or view file is updated.

Create a new file gulpfile.js on the root of your repository with the following contents:

var gulp = require("gulp");
var browserSync = require("browser-sync").create();

gulp.task("default", runBrowserSync);

function runBrowserSync() {
  browserSync.init({
    proxy: "localhost:3000"
  })

  gulp.watch("app/views/**/*", browserSync.reload)
  gulp.watch("app/assets/**/*", browserSync.reload)
}

To run it, just run gulp in a separate terminal after starting the Rails application server (rails s).

A new browser window should open up. When you make any change in the assets folder, your browser window should automatically refresh.

Alternative Gemfile

It's possible to have Browsersync push CSS updates without a full page refresh. As of Rails 5, I don't recommend it since you'll need to disable asset fingerprinting in development. ⚠️

If you decide to go this route though, your gulpfile's runBrowserSync method should look something like this:

function runBrowserSync() {
  browserSync.init({
    proxy: "localhost:3000"
  })

  gulp.watch("app/views/**/*", browserSync.reload)
  gulp.watch("app/assets/javascripts/**/*", browserSync.reload)

  gulp.watch("app/assets/stylesheets/**/*.scss", function (event) {
    browserSync.reload("/assets/application.self.css")
  })
  gulp.watch("app/assets/images/**/*", function (event) {
    var relpath = event.path.split("/app/assets/images/", 2)[1]
    var imagePath = "/assets/" + relpath;
    browserSync.reload(imagePath)
  })
}
Posted on Sunday, July 23, 2017 at 9:49 PM
Zach Ahn
hello(at)zachahn(dot)com
© Copyright 2008–2019 Zach Ahn. All Rights Reserved.