Understanding Webpacker in Rails 6
Tags: rails
Published: 2019-08-28 06:40:14

---
title: Understanding Webpacker in Rails 6
published: true
tags: rails
canonical_url: https://prathamesh.tech/2019/08/26/understanding-webpacker-in-rails-6/
---

Starting with Rails 6, Webpacker is the default JavaScript compiler. It means that all the JavaScript code will be handled by Webpacker instead of the old assets pipeline aka Sprockets. Webpacker is different from asset pipeline in terms of philosophy as well as implementation. In this blog post, we will learn about how Webpacker goes about handling JavaScript.

### What is Webpacker

`webpacker` is a gem which wraps `webpack` - _the popular JavaScript tool used for managing and bundling JavaScript code_ - and provides helpers to use the webpack in our Rails applications. In simple words it provides Rails way of using Webpack. This is very simple definition for a tool which is very powerful but that is enough for us as of now.

_Webpacker wraps webpack in a Ruby gem and provides helpers to use the output from Webpacker in the Rails application._

When you create a new Rails 6 app, you will see following output in the console.

<!--kg-card-begin: code-->
```
       rails webpacker:install
RAILS_ENV=development environment is not defined in config/webpacker.yml, falling back to production environment
      create config/webpacker.yml
Copying webpack core config
      create config/webpack
      create config/webpack/development.js
      create config/webpack/environment.js
      create config/webpack/production.js
      create config/webpack/test.js
           
```
<!--kg-card-end: code-->

You will also find `webpacker` gem in the `Gemfile` by default. The `rails new` command will also install tons of npm packages via `yarn`.

> Old applications which are upgraded to Rails 6, do not get `webpacker` gem installed by default. You need to manually include it in Gemfile and then run `rails webpacker:install`. We will cover how to use Webpacker in an existing Rails application in a latter blog post.

### New destination for the JavaScript code

Before Rails 6, all the JavaScript code is supposed to be in `app/assets/javascripts`. But in a Rails 6 app, the `app/assets/javascripts` directory does not even exist. Instead, we have `app/javascript` directory to host all the JavaScript code. The name is such that it contains the JavaScript part of the application which can be all the code for the frontend part of your application.

Let's go through the contents of this directory in a empty Rails 6 application.

<!--kg-card-begin: code-->
```
Projects/scratch/better_hn master ✗ 2.6.3 ◒
▶ tree app/javascript
app/javascript
├── channels
│   ├── consumer.js
│   └── index.js
└── packs
    └── application.js

2 directories, 3 files
```
<!--kg-card-end: code-->

It contains two directories, `channels` and `packs`. The `channels` directory is generated by Action Cable component of Rails. We can ignore it safely for now. The `packs` directory is significant for us so let's see what it contains.

<!--kg-card-begin: code-->
```
// app/javascript/application.js
require("@rails/ujs").start()
require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")
```
<!--kg-card-end: code-->
### What is a pack?

Webpack has a concept of entry points which are the files that Webpack looks for first when it starts compiling your JavaScript code. Webpacker gem creates the `application` pack in the form of this `application.js` file under `app/javascript/packs`. If you remember the assets pipeline, this file is equivalent to the `app/assets/javascripts/application.js` file.

The `application` pack generated by Rails contains code related to Rails components such as trubolinks, Active Storage and Action Cable.

> You will notice that all the Rails frameworks which have JavaScript component such as Rails-UJS, Turbolinks, Active Storage are migrated to support Webpacker. Even the new frameworks introduced in Rails 6 such as Action Text work with Webpacker.

So the `application` pack is the entry point for all of your JavaScript code. We can create custom packs and place them in the `app/javascript/packs` directory and Webpacker will find them happily while compiling.

This setting is configured by Webpack for us in the file `config/webpacker.yml`

<!--kg-card-begin: code-->
```
# config/webpacker.yml
5: source_entry_path: packs

```
<!--kg-card-end: code-->

If we want Webpack to look for additional directories for the JavaScript code, we can configure the setting `resolved_paths` in the `config/webpacker.yml`. The file is pretty self-explanatory in terms of the configuration options.

### Compiling the JavaScript code

The next natural step is to look into how to compile the JavaScript code using Webpacker and webpack. In development mode, you don't have to do anything. When you run the rails server, the compilation happens during the request similar to how it used to work with assets pipeline.

#### Live reloading using webpack-dev-server

Webpacker generates a file `bin/webpack-dev-server` which can be used for live reloading in the development phase. We have to run the webpack-dev-server separately for this purpose and then we can see live reloading and hot module replacement in action.

#### Production mode

In production, webpacker appends `webpacker:compile` task to the `assets:precompile` task. So if your build pipeline runs `assets:precompile` task it will take care of compiling files to be compiled by webpack as well. As wepack package is part of `package.json`, yarn will take care of installing it so that it can compile the JavaScript code.

### Including the JavaScript code in the app

We have seen how to compile the JavaScript code using webpacker but how to include it in our apps?

For that, Webpacker provides a helper method `javascript_pack_tag`. As the name suggests, we use it to include the webpacker packs in our layout files. This is equivalent to `javascript_link_tag` from the assets pipeline.

<!--kg-card-begin: code-->
```
# app/views/layouts/application.html.erb

<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>

```
<!--kg-card-end: code-->

The `javascript_pack_tag` takes care of making sure that it references compiled assets properly in development mode as well as in production mode similar to the assets pipeline.

<!--kg-card-begin: hr-->
* * *
<!--kg-card-end: hr-->

That's all for today. We got an overview of how Webpacker enables us to use webpack in a Rails 6 application and we understood `packs` in the Webpacker world. We also saw how the compilation happens and how to use the compiled code in the application. In the next post, we will discuss the Webpack philosophy and what it means as a Rails developer to use this new way of writing JavaScript code.

If you want to know more about how to use webpack and Webpacker in Rails 6 to write modern JavaScript, subscribe to my newsletter [Road to Rails 6](https://prathamesh.tech/road-to-rails-6) where I will be writing about not just Webpacker but lot of other articles related to Rails 6.