Thanks for filling out our form!
Here's what happens next:

We'll write you back as soon as possible, right now we might be very busy saving the World. Give us a day or two, we'll contact you for sure.


In the meantime, perhaps you would like to take a look at one of our blog posts that explains

How do we work with our Clients
How we can help you with your business

In Touch,
Prograils Team

Prograils blog

Robert Kaczmarek on 10.07.18 in Ruby on Rails
Post annie spratt 608001 unsplash

Adding Webpacker 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.

Who is this Webpacker guy?

Webpacker is a gem which provides integration with webpack and yarn in your Rails app.
From 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. That means we can use some ES6 code, as well as React, Angular, Vue, Elm or any other JS framework, and webpack will translate it to 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.

Let's get a bit technical

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?

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 a 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'

End note

Webpacker is a very powerful tool, opening multiple doors for us. We can now level up our application with a slick frontend, streamline user's experience and add new complex functionalities. Similarly to the i18l Ruby gem providing internationalization to your app, it increases your product's attractiveness in many ways. But this brief introduction is just only a beginning - in my next post, I will show you yet another new JS kid - StimulusJS. It will be a great example to present the capabilities of webpack and modern JS. Meanwhile, learn more on how we go about our Rails development process!

Photo by Annie Spratt on Unsplash.com

Share on
comments powered by Disqus