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.
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
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 runrails 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.
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
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.
// app/javascript/application.js
require("@rails/ujs").start()
require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")
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
# config/webpacker.yml
5: source_entry_path: packs
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.
# app/views/layouts/application.html.erb
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
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.
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 where I will be writing about not just Webpacker but lot of other articles related to Rails 6.
Top comments (0)