Using Webpack with Rails

In the last week, I’ve seen 2 other techniques for using Webpack with Rails, besides the technique I’m using which is illustrated in this git repository: GitHub - shakacode/react-webpack-rails-tutorial: Example of integration of Rails, react, redux, using the react_on_rails gem, webpack, enabling the es7 and jsx transpilers, and node integration. And React Native! Live Demo:

Before discussing which technique for Webpack, there’s a few simple reasons I love it with Rails:

  1. Total integration with the NPM community for getting JavaScript libraries.
  2. Easily enables ES6 and JSX (ReactJs)
  3. Webpack Dev Server for Hot Module Replacement.

Let’s compare and contrast these techniques. What are the advantages? Disadvantages? Why did you pick one of them?

Justin Gordon: Webpack Stand Alone with Rails

Article: Fast Rich Client Rails Development With Webpack and the ES6 Transpiler

Updated example: GitHub - shakacode/react-webpack-rails-tutorial: Example of integration of Rails, react, redux, using the react_on_rails gem, webpack, enabling the es7 and jsx transpilers, and node integration. And React Native! Live Demo:

Advantages

  1. For Rails, rather than changing the asset pipeline, webpack is only used to generate a single JavaScript file that contains application code and npm JavaScript dependencies. This is transparent and simple. I’m only using WebPack within Rails for JavaScript, and not for other assets, such as Sass, Images, or Fonts. I’d rather let the asset pipeline handle those assets. For development
  2. I’m developing my JavaScript heavy parts of the application completely without Rails, and instead using the Webpack Dev Server to serve up mock JSON responses. I find this works well for doing ReactJs work. I really like the hot reload. This server loads the same Twitter Bootstrap configuration, images, fonts, etc, as does the Rails server.
  3. I like how everything is 100% transparent.
  4. The sample project shows this working and even deploys to Heroku.

Disadvantages

  1. It’s a bit of work getting this setup, but the example should make this pretty easy.
  2. By being transparent, there might be a bunch to get your head around.

Kevin Old: Webpack’s Dev Server for Rails Assets

Configure Webpack Dev Server and React Hot Loader with Ruby on Rails: Live Edit React.js Components in Ruby on Rails

This technique is based on the examples I generated. However it differs with the way that the development mode of Rails gets some assets from the Webpack dev server, which is running side by side. It seems that the hot reload may work inside of Rails, which would be quite exciting. I haven’t tried, so I can’t say.

I opened a github issue to try to incorporate some of these ideas in the example:

Dan Ott: webpack_rails Gem

Dan Ott has made a gem, webpack_rails.

webpack_rails is built to be used beside sprockets-rails, or in place of sprockets-rails, but not within sprockets-rails.

Some of the pain with managing JavaScript dependencies in Rails comes from trying to shove NPM thinking inside of Sprockets thinking, which are completely different. Building a system with support for two different paradigms is not the goal of this project.

If it’s helpful, it can be thought of this way - we’re trying to build an alternative asset pipeline, that lives at /webpack instead of /assets. This avoids running into unexpected behavior, while providing clear division of labor between the tools.

I’m hoping that Dan might be able to comment here. Part of what I like about my transparent technique is just that it’s transparent. I have no fears that with upgrades to Rails that the simple technique will break.

Then again, a gem that does the magic might be appealing for some.

Convention over configuration is paramount in Rails. Introducing a new build tool is not convention over configuration. All three approaches have decided to sacrifice the Rails convention of asset packaging for the benefits of using Webpack.

The challenge is how to communicate this decision to teammates, future maintainers, or even your future-self.

READMEs and directory structure are not the most effective way of communicating these kinds of decisions. Whether it’s right or not, reading the manual often comes as a last resort when the environment isn’t working as expected from running rails server.

Writing a gem allows for failing loudly at runtime on every unmet expectation. Even better, these failures can include messages that guide others (including the future-self) towards making the environment work. This strategy of loud failures that provide help is one of the things that makes working in React so delightful.

Here’s an example of Failing loudly in webpack_rails. Failing loudly to communicate the use of Webpack is the largest advantage of using webpack_rails.

@danott The way I have things setup, I use a Procfile to run webpack -w to refresh the JavaScript during development.

Any chance that you have a sample project with your gem? Or could you maybe create a fork of https://github.com/justin808/react-webpack-rails-tutorial so we can compare the two techniques?

It seems like your strategy uses Webpack for all assets, whereas my strategy is just for the JS file. There could be pros and cons to either approach.

Have you tried deploying your gem to Heroku? It took a bit of work to get my strategy working, but once working, it works great.

webpack_rails has no preference on what assets are served using it. At it’s essence, webpack_include_tag is a wrapper around javascript_include_tag that fails loudly when Webpack’d assets aren’t available. The generators are conventions that will be tweaked to suit a projects’ needs.

  • /assets/application.js goes to Sprockets in development.
  • /webpack/dev-server/application.js goes to Webpack in development.
  • /webpack/application.js expects to be found in /public/webpack, similar to precompiled asset conventions using Sprockets.
  • The fact that the source file is defaulted to /app/assets/javascripts/application.js is arbitrary. You could just as easily set the application.js entry to /any/old/path/you/want/application.js in webpack.config.js. You raise a good question that something like /app/webpack/application.js may be even more obvious, and clearly communicate the decision to not use the Rails asset pipeline.

Users have many reasons for wanting to use Webpack. One use is building single page applications. One use is wanting to use CommonJS requires.

I don’t have any sample projects using webpack_rails to share at the moment (they’re all private repositories).

It would be interesting to see you fork your repo, and try using the webpack_rails gem. My brain is already biased with implementation and utilization details of the gem, whereas your experience will surface the assumptions that are sitting cozily in my blind spots.

Have you got the deployment steps to Heroku?

I’m slammed with tons of client work right now, so I won’t have a chance to try that soon.

I do say that having an example project with deployment steps to heroku will probably help with adoption.

Pull requests welcome. :blush:

Likewise! I created a bunch of issues for which I’m looking for help.

On a separate note, for one project of mine, I’ve found it useful to create a mock JSON API. You can see that in this file. I really like using WebStorm opened up to the /webpack directory and having a myopic, non-rails view of the world while focusing on the JavasScript and AJAX. @danott, how does that fit into your system?

https://github.com/justin808/react-webpack-rails-tutorial/blob/master/webpack/server.js