Babel, Rails 5 and Sprockets 4 with Sprockets Commoner

For some of our Rails projects we have replaced the Rails Asset Pipeline with Webpack and we're quite happy with it.

Webpack has so many nifty features and combining it with Babel we can write next generation JavaScript today.

But sometimes, especially for smaller projects such as our gymbot (deprecated), you just don’t want Webpack. Having it would be an overkill. So what are our options if we’re looking for something leaner. What are our options? There is sprockets-es6 but it’s highly experimental and not very well maintained. Another option is to drink the kool aid and try out Sprockets 4.0.0.beta2.

Sprockets 4 got a major redesign so that tools like Babel can easily plugin into the system - also say hello to sourcemaps. But merely using Sprockets edge only gets us half the way - we would still missing things like npm controlled dependencies or different environments. This is where Sprockets Commoner comes into play. Sprockets commoner is meant as a replacement for Browserify or Webpack. Setting everything up is fairly easy. The first step would be to update your Gemfile:

rubygem 'sprockets', '4.0.0.beta2'
gem 'babel-transpiler'
gem 'sprockets-commoner'

The next step is to create a manifest in app/assets/config/manifest.js that declares how your assets shall be treated by Sprockets:

js//= link_tree ../images
//= link_directory ../javascripts .js
//= link_directory ../stylesheets .css

Then you setup a package.json (in your Rails root) where you include babel-core and all your application dependecies:

  "private": true,
  "dependencies": {
    "babel-core": "^6.13.2",
    "babel-preset-es2015": "6.9.0",
    "lodash": "^4.14.2"

You probably also want to create a .babelrc (also in your root directory) to declare your babel transforms

  "presets": ["es2015"]

From then on you can use all the ES6 magic in your application.js:

jsimport {map} from 'lodash';
console.log(map([1, 2, 3], (n) => n * 3));

If you want to have more control over Sprockets Commoner you configure it in an initializer:

ruby# In config/initializers/sprockets_commoner.rb
Rails.application.config.assets.configure do |env|
    # include, exclude, and babel_exclude patterns can be path prefixes or regexes.
    # Explicitely list paths to include. The default is `[env.root]`
    include: ['app/assets/javascripts/subdirectory'],
    # List files to ignore and not process require calls or apply any Babel transforms to. Default is ['vendor/bundle'].
    exclude: ['vendor/bundle', /ignored/],
    # Anything listed in babel_exclude has its require calls resolved, but no transforms listed in .babelrcs applied.
    # Default is [/node_modules/]
    babel_exclude: [/node_modules/]

In our application everything went pretty smoothly. Thanks to Shopify for releasing Sprockets-Commoner open source. If you also want to play with cutting edge technologies like ES6, Rails or Elixir feel free to apply at 9elements.

Cofounder of 9elements. Software alchemist since he was a kid. Knee deep in tech with building things in React, Rails or Solidity.