Rails Webpacker Installation & Adding to a Legacy Rails App
Some say there was not a day without a new JavaScript framework these past years - that means JS is evolving every day. The problem is, Rails does not provide any proper support for those new toys. Unless you get the hang of a gem called Webpacker, which comes bundled with Rails 5.1+.
But when I tried to introduce it to a Rails-newcomer, it struck me that making a switch from (or adding) webpack (and others) to an existing legacy Rails app is not that easy. Also, what's the sense of doing it anyway? We will try to make everything clear today.
Table of content
- What is webpacker?
- How to install Webpacker in Rails?
- What is webpack-dev-server?
- Throwing an eye on the new architecture
- Endnote: How your Rails app can benefit from webpacker
What is webpacker?
Webpacker is a gem which provides integration with webpack and yarn in your Rails app.
From the webpack's page we can read that "webpack is a static module bundler for modern JavaScript applications" - in short, it's used to compile modern JavaScript modules so that our browser can understand it.
This means we can use some ES6 code, as well as React, Angular, Vue, Elm or any other JS framework, and webpack will translate it into JavaScript.
Yarn, on the other hand, reads as fast, reliable, and secure dependency management - think of it as a bundler, but for your JavaScript modules.
Bear in mind that Webpacker's main purpose is to serve JavaScript, as well as assets like CSS, images and fonts for component-based JavaScript, but it is also possible to use it for your entire application's assets.
Psst, have you heard? Webpack is the new JavaScript bundler for Rails 6.0!
Rails 6 made webpacker as a default JavaScript compiler tool. That means you no longer need to worry to install it manually. It will be installed automatically by Rails application generator. So you are good to go from the start!
Curious about other new features of Rails 6.0? Learn about Action Mailbox, Action Text, multiple database support, parallel testing and others from this article.
How to install Webpacker in Rails?
To install Webpacker in your legacy Rails application, simply add the gem webpacker to your Gemfile.
# Gemfile
gem 'webpacker', '~> 3.5'
or if you prefer to use the master branch
# Gemfile
gem 'webpacker', git: 'https://github.com/rails/webpacker.git'
After that, just run two commands in the terminal:
# bash
bundle install
bundle exec rake webpacker:install
When this is done, what is left to do is to add packs tag to our layouts, i.e. application, just like standard tags:
-# views/layouts/application.haml
= javascript_pack_tag 'application'
= stylesheet_pack_tag 'application'
At this point, we are done with installing Webpacker in a legacy app - it's time to use some modern JS code!
But when you are creating a new app and want to have Webpacker installed right from the start, use this command when creating a Rails 5.1+ project:
# bash
rails new myapp --webpack
and you are good to go!
Quick note - if you are using Rails 5.2+, then you need to allow webpack-dev-server to load your packs. You can do this by adding this snippet to your CSP configuration:
# config/initializers/content_security_policy.rb
policy.connect_src :self, :https, "http://localhost:3035", "ws://localhost:3035" if Rails.env.development?
What is webpack-dev-server?
You might ask what is this webpack-dev-server, so let's pause for a second and explain it.
When you are developing an application, Webpacker compiles your JS modules on-demand - so whenever you refer to any of your pack assets, it will compile it and serve it to your browser.
But sometimes you just have too much JavaScript and on-demand compilation might be too slow to handle it - that is when webpack-dev-server comes in handy.
It compiles all your packs upfront and also provides live code reloading - so whenever you make any change to your JS pack, it will recompile it.
Using webpack-dev-server is very easy, because Webpacker comes up with binstub for it. All you have to do is run in your terminal (in your project directory), alongside your Rails server:
# bash
./bin/webpack-dev-server
Throwing an eye on the new architecture
The structure for your newly created asset pipeline looks like this (taken from Webpacker's docs):
app/javascript:
├── packs:
│ # only webpack entry files here
│ └── application.js
└── src:
│ └── application.css
└── images:
└── logo.svg
As you can see:
- in packs we will have all of our JavaScript files
- in src we will have stylesheets
- in images we will have... images
To source images through webpack, you need to import them to your application.js (or any other file).
You can do this by either normal import
// javascript/packs/application.js
import './images/some_image.png';
or if you have a big number of images, you can use require.context() to load all the files in a given folder
// javascript/packs/application.js
require.context('images', true, /\.(svg|png|jpg)$/igm);
Then to use them in your Rails template code, simply use the asset_pack_path helper, like this:
= image_tag asset_pack_path 'images/some_image.png'
Endnote: How your Rails app can benefit from webpacker
Webpacker is a very powerful tool, opening multiple doors for us. We can now level up our application with a slick frontend, streamline user experience and add new complex functionalities. Similar to the i18l Ruby gem providing internationalization to your app, it increases your product's attractiveness in many ways.
Photo by Annie Spratt on Unsplash.com