Rails 6 has added Webpacker as the default JavaScript compiler instead of Sprockets. Thus, all javascript code will be compiled with the help of webpack by default.
Before Rails 6
The JavaScript was compiled with Sprockets Rails by default and resided in app/assets/javascripts
directory. Stubs would be created when using scaffold generators.
With Rails 5.1+, we could provide an option to use Webpacker as the compiler while creating a new rails application,
rails new myapp --webpack
Or to use it with existing Rails application,
# Gemfile
gem 'webpacker', '~> 4.x'
And then install it with the Rails application,
bundle
bundle exec rails webpacker:install
After Rails 6
When we create a new application with Rails 6, the Webpacker gem will be installed and webpacker:install
will be run by the Rails application generator.
By default, The app/javascript
directory will host the JavaScript files. The existing JavaScript code for Active Storage, Action Cable, Turbolinks, and Rails-UJS will be loaded by a new application.js
pack in app/javascript
directory.
The Action Cable stubs will be created in the app/javascripr/channels
directory and will use ES6 instead of CoffeeScript. Note that no other JavaScript stubs will be created by default when using the scaffold generators.
What is Webpacker?
Webpacker is a gem which allows easy integration of JavaScript pre-processor and bundler with Rails. It provides various helpers and configuration options to use webpack easily with Rails.
Webpacker directory structure with Rails 6,
The app/javascript
directory contains,
app/javascript:
├── channels:
│ # action cable channel files here
│ └── consumer.js
│ └── index.js
├── packs:
│ # only webpack entry files here
│ └── application.js
The packs
directory contains entry points for webpack. All the files in the packs
directory are compiled by Webpacker. The application.js
pack by default includes JavaScript code for Active Storage, Action Cable, Turbolinks, and Rails-UJS,
require("@rails/ujs").start()
require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")
How to use Webpacker with packs?
With the help of packs, Webpacker provides a convenient way to access and use JavaScript required for different layouts in the Rails application. The packs can be accessed via helper methods javascript_pack_tag
and if css styles are being imported in pack files, stylesheet_pack_tag
.
For instance, with Rails 6, the app/javascript/packs/application.js
pack will be included by default in app/views/layouts/application.html.erb
layout as follows,
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
It is encouraged to place the actual application logic in a relevant structure within app/javascript
and only use the pack files to reference that code so that webpack knows it needs to be compiled.
How to configure Webpacker?
The configuration information for Webpacker lies in config/webpacker.yml
. We can change options like source path, packs path and many more from the configuration file.
The environment specific JavaScript configuration files for webpack can be found at config/webpack
directory. More on webpack configuration with Webpacker here.
Compilation
Keeping the process similar to the previous assets pipeline, the JavaScript compilation happens along with the request while running the Rails server in development mode.
In production mode rake assets:precompile
does the job. The assets:precompile
rake task runs webpacker:compile
by default to generate webpack compiled assets.
We can also use live reloading and hot module replacement in development mode with the help of binstubs
provided by Webpacker. More on that can be found here.