I’ll explain my choices below, but I’d like to start this post with exactly what you need to get started.
# Gemfile gem "browserify-rails" group :development, :test do # Your choice of test library. # Also available, teaspoon-mocha / teaspoon-qunit gem "teaspoon-jasmine" # Teaspoon's front-end is written in CoffeeScript but it's not a dependency gem "coffee-script" end
Install the requisite npm packages locally (don’t commit
node_modules to source control, just
npm install browserify browserify-incremental babelify babel-preset-es2015 --save
bundle exec rails g teaspoon:install
Write ES6 modules and tests!
Run the tests with
rake teaspoon or visit the web runner at
I have also provided an example Rails site showcasing this functionality.
Gemfile, increase the apps boot time, and further complicate upgrades.
So how do we hook up
npm packages to the Rails Asset Pipeline? There are a number of options available to us now, including foregoing the Asset Pipeline entirely and building a custom pipeline with tools like webpack and brocolli, but given that Rails already has a pipeline, doing so adds a significant learning hurdle for any developer coming onto the project.
browserify-rails, adding and using
npm packages is simple. Want to use
react? Install and configure:
npm install react react-dom babel-preset-react --save
# config/application.rb config.browserify_rails.commandline_options = "-t [ babelify --presets [ es2015 react ] ]"
browserify-rails (seen above) I had what I wanted. ES6 in the app and in tests, using the same tools. Win!
But what about…
react-on-rails, this library configures a
webpack-based asset pipeline, thus supporting further extensions and library usage, but again adds a large cognitive load to add to a Rails app.
Sprockets 4 or sprockets-es6?
bower, grunt, gulp, brocolli, webpack, …
There are definitely valid reasons to go about building your own asset pipeline using these tools. There is a lot of power behind having full control over how assets are processed in your app, but if you’re like me and want to keep using the Rails Asset Pipeline, these tools are not trivial to use and add extra cognitive overhead both in understanding what’s going on and maintaining the stack over time.
I have seen simple setups using
bower, configured to install packages into
npm is available in
bower, and you’re adding another level of maintenance to the system. Similarly with rails-assets, which is simply bundling up
bower and on another external service at https://rails-assets.org/.
With the research I’ve done, I do believe that
teaspoon are the best route forward for most Rails apps to make use of ES6,
npm modules and
Object.assign, I recommend grabbing the
npm install babel-polyfill --save
Teaspoon uses phantomjs as the default test runner, but that may not work for some libraries. I’m not sure where the problem is, and will update if I find a fix, but my use of React and Draft.js is causing problems with headless test runs, so I am currently using the
selenium-webdriver runner to run the tests in Firefox directly. If you’re using CI, you’ll need to configure your test runs to be able to open up Firefox (e.g. How to on Travis CI)
Travis CI caching
npm install on every test run can really slow down a test suite. Travis supports various types of caching and if you’re using Travis you’ve probably already got
bundler caching enabled. I would recommend also caching the
node_modules directory, but to properly cache both, you need to convert your configuration to a list of directories:
# .travis.yml cache: directories: - vendor/bundle - node_modules
Hey, thanks for the post!
I’m having some trouble to use polyfill the same way you mentioned. I successfully import it on application.js but it does not include any new API on the file where it’s imported (application.js). I’m missing any build process on browserify?
Thanks for the post. I’m hoping to use this setup, but I’m having trouble getting the ES6 transpiling to work. I’ve tried to follow your instructions meticulously, but it keeps giving me ‘Unexpected token export(or import)’ syntax errors. Were there any steps that were assumed in the set up of browserify-rails that are necessary to get this functioning?
@Oswaldo: Do you see babel-polyfill code at all in the resulting application.js file? I have not had any issues so far getting the polyfill to apply.
@Todd: I double checked my setup with what’s in the post and I don’t see any differences. I assume the browser is throwing the “Unexpected token” error? Which would imply that the transpiling isn’t happening at all, or at least not on all files. Do you have output in your development log showing browserify compiling files when you request the page?
Jason, thanks for responding.
I’ve implemented a hack I saw listed (in this comment -> https://github.com/browserify-rails/browserify-rails/issues/19/#issuecomment-73743770) on a browserify-rails github issue for ES6 transforms. Narrows it down to the browserify_processor.rb file of the gem not adding checks for ES6 syntax.
I’m just curious why you and others are not having that problem when it seems you’re using strictly ES6 module syntax.
Now I’m having trouble trying to do server rendering for React using your colleague Jon’s guide (http://collectiveidea.com/blog/archives/2016/04/13/rails-react-npm-without-the-pain/), so here I go to comment on that post.