Marrying Rails, Turbolinks and JavaScript Custom Elements

Robert Glaser

Rails 5.1 just arrived and brought with it a curated setup for webpack (aka webpacker; lots of generated boilerplate code that needs to be updated whenever webpacker updates). Think what you want about webpack, but it’s the new default for JavaScript module loading and bundling in Rails and therefore here to stay. So here’s a quick post on how to get the new JavaScript goodness up and running with your existing Turbolinks setup.

How do we start using native ES2015 / ES6 Custom Elements with Turbolinks?

As custom elements bring their own life-cycle management we need to make sure that our components aren’t re-evaluated by Turbolinks on every new page visit. It’s helpful to facilitate importing and registering our custom elements in their own JavaScript bundle (or “pack” in webpacker tongue). By doing this we can tell Turbolinks to leave elements.js alone and don’t touch it during page transitions:

<%= javascript_pack_tag 'elements', 'data-turbolinks-eval': false, defer: true %>
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload', defer: true %>

Imagine our elements.js looks like this:

import AlertMessage from './components/alert-message'
customElements.define('alert-message', AlertMessage)

In Rails’s default application.js pack we can then import Turbolinks and start it:

import Turbolinks from 'turbolinks'

This relies on Turbolinks being available via npm. By integrating Turbolinks via npm you still need the gem for some Rails internals, but you have to disable the automatic require. Otherwise Rails will try to mangle Turbolinks into its own Sprockets-based asset pipeline. We don’t want that for JavaScript bundles as we’re using webpack now.

gem 'turbolinks', require: false

By disabling automatic requiring you’re expected to manually include Turbolinks’ redirection helpers in your ApplicationController:

class ApplicationController < ActionController::Base
  include Turbolinks::Redirection
  # ...

That’s all you need to get Rails to run smoothly with Turbolinks and a npm-/webpack-based asset pipeline for your JavaScript custom elements. Their native hooks like connectedCallback() and disconnectedCallback() now all perform as expected.

Thumb dsc01726

Robert Glaser arbeitet als Senior Consultant bei innoQ und beschäftigt sich seit über 10 Jahren mit der Entwicklung von ergonomischen Webanwendungen. User Experience und Interface-Design zählen zu seinen besonderen Interessen.

Weitere Inhalte


Um die Kommentare zu sehen, bitte unserer Cookie Vereinbarung zustimmen. Mehr lesen