Mayor David Adewole
9 min readNov 14, 2017

--

Rails + Angular + Webpacker Gem Like a Pro.

Webpacker gem in Rails lets you implement an additional pipeline for building modern frontend Javascript alongside your Rails application using popular frameworks like Angular.

Webpack, if you are not yet familiar with it, is a module bundler. It’s main purpose is to bundle Javascript files for usage in a browser, yet it is also capable of transforming, bundling or packaging. It is an asset pipeline that supports most of the modern features of frontend web development along with everything we are used to from Sprockets.

Before the Webpacker gem was introduced in Rails version ≥ 5.1, people experienced a lot of difficulties trying to configure Rails to work with Webpack. A large portion of the Rails community, most especially the big enterprises were beginning to move their asset pipeline management away from Sprockets (the default Rails library for compiling and serving web assets) to Webpack.

But why is it so important to migrate from Sprocket to Webpack? You may be wondering by now.

In the last few years it became clear that Sprockets could no longer keep up with the pace at which the frontend web development ecosystem is evolving. Regular problems such as support for the latest releases of frameworks such as Sass (the CSS extension language), lack of source maps and a drop in support for compressed assets which eventually made compilation of assets extremely slow made it important to migrate from Sprockets to Webpack. Between 2015 to 2016 a lot of companies switched their asset management from Sprockets to Webpack.

So in December 2016 DHH announced Webpacker

DHH — Founder of Ruby on Rails announcing the Webpacker

The main purpose of this post is to introduce how to use Webpacker in your Rails project beyond the basics that we see in articles all over the internet. Personally, I feel like the Rails community has a personal beef with Angular. Almost no one is writing about Rails and Angular integration. I’d taken note of this as far back as last year when the full version of Angular 2 was released and I could not find a single post on how to consume Rails API resources in Angular. So I started a YouTube channel that is dedicated to that. Check this link for some video tutorials.

This is going to be a series of posts addressing some of the most important aspects for a Rails project such as Consuming Rails API data in Angular, Allowing Angular to handle Routing, Server side enabled Pagination and more.

So lets go ahead and create a Rails project already.

NB: I assume that you have the latest version of Ruby, Rails and Postgres installed on your machine so I won’t be talking about how to do that.

We are going to use Postgres as our database, it uses SQLite by default. We will also skip using TurboLinks because it’s going to clash with the Javascript we’ll be writing when we start using Angular, And also going to skip spring installation and Test:Unit installation because well, most people use RSpec these days. So if you have Rails and Ruby installed on your machine, go ahead and run this command in your command line, that would be the Terminal on a Mac.

rails new angular-webpacker-app --skip-turbolinks --skip-spring --skip-test -d postgresql 

The rails new command created a new rails application as you would expect. Let’s go ahead and change the current directory to that of the app we just created and also open the folder in your favorite text editor.

cd angular-webpacker-app➜ angular-webpacker-app git:(master) ✗ subl . // Run this command - subl . to open the current directory in Sublime Text. 

Next we will set up the database, so go ahead and run the next command.

NB: Take note that ➜ angular-webpacker-app git:(master) ✗ from now on signifies the start of a command line.

➜  angular-webpacker-app git:(master) ✗ rails db:create

The result of the command above rails db:create , if everything goes well on your end is:

Created database ‘angular-webpacker-app_development’
Created database ‘angular-webpacker-app_test’

So now we can run the rails server to see the rails app in action.

➜  angular-webpacker-app git:(master) ✗ rails server

You can now visit http://localhost:3000 to see the new Rails 5.1 welcome page as shown in the screenshot below.

Rails new app welcome page

Now we will create a simple page which we will use to validate and test that we’ve installed and added Webpack successfully. We will call this page home. So open up the route.rb file located in the config folder. My route.rb file now looks like this:

Rails.application.routes.draw do
root to: "home#index"
end

Next, create a controller file app/controllers/home_controller.rb:
my home_controller.rb file now looks like this.

class HomeController < ApplicationController
def index
end
end

Finally, create app/views/home/index.html.erb with some content:

<header>
<h1>
Welcome Home.
</h1>
<section>
<p>
Home of the Webpacker App.
</p>
</section>
<h6>We're using Rails <%= Rails.version %></h6>
</header>

Now reload your app and you should see the page we’ve created.

So now that you have a working Rails app, let’s install Bootstrap, this requires learning how to use Yarn to install Webpack, which will serve up our CSS and Javascript files (this is when Webpack replaces Sprockets).

We use Yarn to manage our Project’s dependencies like Angular, Bootstrap CSS and other Javascript libraries then use Webpack to serve it up in the browser. Rails version ≥ 5.1 includes support for Yarn by default. As mentioned above Sprockets is missing most of the modern features of frontend web development. If you want to use Javascript framework like Angular then you will need some features that are not available with Sprockets. Now let’s go ahead and install Yarn.

If you are on a Mac and you already use Homebrew, I advise you to install yarn by running the brew command. This is based on personal experience.
I had some issues with Yarn installation on my Mac in the past because of conflict in versions of yarn installed through NPM and Brew, that limited some of my projects from working. So if you are installing Yarn by NPM stick to that and if you are using Homebrew stick to that as well. It is not advisable to have both installations from NPM and Brew on your machine at the same time. I prefer the brew installation because I get the most updated version all the time just by running brew upgrade, which updates all my brew packages. So to install yarn run the following command. Btw, also note that you’ll need to install Node to get Yarn to work. Check this install page to see different ways to install yarn on different machines

brew install yarn

Next, let’s install and configure Webpacker.
Rails 5.1 includes and optional gem called Webpacker that is the official way to use Webpack in a Rails application. Webpacker includes a set of generators and helpers that creates a Webpack configuration. So first we will add it to our Gemfile:

gem 'rails', '~> 5.1.4'
>> gem 'webpacker' // Add webpacker gem to your Gemfile
gem 'pg', '~> 0.18'

Then we will install it with Bundler by running

➜  angular-webpacker-app git:(master) ✗ bundle install

We can now use Webpacker to install and configure Webpack for our Project by using the Rails task, webpacker:install
Run the following command:

➜  angular-webpacker-app git:(master) ✗ rails webpacker:install

If all goes well, you should see a very long output, a lot of files were created, most of which are created to configure Webpack, and you will also see that a file called package.json has been created in the root of your application. This file is analogous to the Gemfile in that it lists third-party libraries that we will use in our application.
Running yarn install is the Javascript equivalent of bundle install.

Our development workflow with Webpack requires a second server to be run that serves up our Javascript and CSS. Unlike with Sprockets, which executes inside our Rails app when we run rails server, Webpacker runs outside of Rails using it’s own server, called webpack-dev-server (which is already added to the devDependencies in your package.json file). This means we need a way to run this server, but also a way to tell our Rails views to get Javascript and CSS from this server.

The command to serve up our Webpack-managed code is bin/webpack-dev-server. While we could run this in another window alongside the already running rails server, that’s rather cumbersome and inconvenient. Instead we can use a Ruby gem called Foreman. Foreman allows us to specify any number of commands to run at the same time and in the same window. First, let’s install Foreman by adding it to your Gemfile and running bundle install afterwards:

gem 'rails', '~> 5.1.4'
gem 'webpacker'
>> gem 'foreman' // Add foreman to your Gemfile.

To configure Foreman, list all the commands you want to run in a file called Procfile. The format of a Procfile is a series of lines, each having a name, followed by a colon, followed by the command to run.
For our purpose we want to run both rails server and bin/webpack-dev-server. So create Procfile in the root directory of your Rails app and add the following code like so:

//angular-webpacker-app/Procfilerails:   bundle exec rails server
​webpack: bin/webpack-dev-server

Now you can run these commands with the single command line foreman start. Now this will be the way you should run your Rails + Webpacker application from this point onward.

NB: Take note that rails server which was running earlier on now needs to be stopped for foreman start to run successfully. You will also notice that Foreman is running on http://localhost:5000/. Go ahead and give it a try!

With this in place, we can now serve up Javascript and CSS managed by Webpack to our Rails application. To verify that this is true let’s bring in Bootstrap into our application. Navigate to app/javascript/packs/application.js a file that was created by Webpacker during the installation. It includes a welcome code

console.log('Hello World from Webpacker')

Let’s get this to show in the console of our browser. To do that, we’ll use the helper methods provided by the Webpacker gem. javascript_pack_tag to serve up Javascript files and stylesheet_pack_tag to serve up CSS files. We will add them in our main application layout file. So navigate to app/views/layouts/application.html.erb and add the following code:

<!DOCTYPE html>
<html>
<head>
<title>AngularWebpackerApp</title>
<%= csrf_meta_tags %>
<%= stylesheet_link_tag 'application', media: 'all' %>
<%= javascript_include_tag 'application' %>
>> <%= stylesheet_pack_tag 'application' %>
>> <%= javascript_pack_tag 'application' %>
</head>
<body>
<%= yield %>
</body>
</html>

If you refresh you browser now you will get an error:
ActionView::Template::Error (Webpacker can’t find application.css in /Users/mayor/YouTubeClasses/angular-webpacker-app/public/packs/manifest.json. That’s because of course we are importing the application file using stylesheet_pack_tag but there is no corresponding application.css file so let’s go ahead and create that.
Create app/javascript/packs/application.css:
Let’s just increase the font-size of all HTML elements on page by 50px to verify everything is working fine. Add the following code to application.css

html {
font-size: 50px;
}

Then import the application.css file into the application.js file like so:
The reason is that with Webpack, all assets are managed from a JavaScript file. So to tell Webpack to manage a CSS file, we need to import it into the JS file.

import "./application.css";
console.log('Hello World from Webpacker')

This is the result after refreshing my browser. Depending on your machine, you might need to restart your server to get this to work.

The result after refreshing the browser. We imported CSS with Webpacker and served it up in the browser.

Now let’s download and Set up Bootstrap CSS.

With Webpack’s initial setup out of the way, bringing in Bootstrap and other Javascript libraries becomes relatively straightforward.

// To add the latest version of bootstrap
➜ angular-webpacker-app git:(master) ✗ yarn add bootstrap@4.0.0-beta.2
// To add bootstrap 3
➜ angular-webpacker-app git:(master) ✗ yarn add bootstrap@3

To use bootstrap in our project we import it by adding the following line in the app/javascript/packs/application.js file

import "bootstrap/dist/css/bootstrap.css";

If all goes well the font on the page will change to the default Bootstrap.

That’s all the setup we need to use Webpacker in a Rails application. In the next post we will install Angular and configure it to work seamlessly with our Rails application where we will be consuming a Rails data in the Angular application using TypeScript.

If you like this tutorial or find it helpful, please give it a clap (up to 50), so other people can see it. Also do not hesitate to ask questions, if any, in the comment below. You can also follow me on here and on Twitter to stay updated on the next tutorials. Thanks!

--

--