Disclaimer: This is not a introductorial post about Webpack or about using Webpack with Rails, if you need an intro I would recommend you to read the Intro to Webpack by Kimberley Cook and if you want to read about how to integrate it with Rails you can read the awesome post by Samuel Mullen about this topic.
I started to play with Webpack a couple of days ago exploring it as alternative to Sprockets in the upcoming version of Rails (5.1? 6.0?), with that on mind I wanted to check how far is possible to go integrating Rails with Webpack without having to change current Rails conventions (e.g folder structure, routes for assets, support for sass/coffee, etc), after of checking many integration projects (react_on_rails, webpack-rails, etc) and based in the configuration suggested by Samuel Mullen in his blog post and many (so many!) other blog posts I was able to get my fork of the TodoMVC app (forked from the Rails + Angular.js + Yarn + Babel version of TodoMVC by Liceth) working:
You can check the history of commits to see how everything was done but I want to leave some additional notes about the process here:
I was able to keep standard Rails folder structure
Using loaders I added support for Sass, CoffeeScript (for compatibility with our current standards) and Babel (TheFuture™ is now).
I used ExtractTextPlugin
to deal with CSS, in the example is not used for fonts/images inside of
CSS but I tested it and worked successfully, one thing that I see was that
during development I had to refer to images/fonts using relative paths
(e.g inside of
application.css I had
url(../images/rails.png) to get the
image living under
app/assets/images/rails.png), I need to research more about this.
I added a preloader for erb files for the erb files that are part of the asset pipeline, I forked it and changed it to use Erubis instead of the stdlib ERB. (Thanks to rhys-vdw for merging the Pull Request and releasing a new version so fast!!)
application.scss to be able to load external
stylesheets using the sass
Moved the entire JS app code from globals to modules, it wasn’t so hard because the app was pretty small but I can imagine that this would be a hard work in bigger applications not based in modules right now.
I disabled Sprockets entirely, so I don’t have to deal with problems like
double-fingerprinting. In new apps this is easier to do passing the
--skip-sprockets option to
rails new command.
I was able to run the app (webpack + rails) with one single command in two ways:
rails to run
webpack (as child process) in watch mode and emitting the assets to
tmp/webpack in dev mode and using
ActionDispatch::Static to serve the assets. This is all done in one initializer
And finally I discovered that Webpack 2 is almost ready (looks like only the docs are stopping the release of the new version), it has so many exciting new features including Tree Shaking and probably I should be using that version, so I’ll work later in the upgrade to Webpack 2 beta.
I would continue checking what else can be improved and I’ll update this post with my new findings.