Webpacker

Webpacker is a gem which wraps webpack, a Javascript tool for compiling and bundling assets (JS, CSS). When Webpack is executed within a project, it constructs a dependency graph of the Javascript code and generates an output set of Javascript files. These JS files are transferred to the client web browser.

In Rails 6, Webpacker is the default Javascript compiler, replacing sprockets (another library for compiling and bundling Javascript).

Packs

Webpack compiles assets (JS, CSS) into packs, which can be imported into a specific file in your application. Webpack has created an ERB helper method, javascript_pack_tag, which creates an HTML script tag within a view.

Past versions of Rails used different package managers to compile assets, and saved assets in the app/assets directory. Rails 6 is integrated with webpack, and by convention assets are saved in app/javascript/. Admittedly, it is a little confusing to save CSS files and images in a folder named javascript, however, this is the default file structure and it is easy to work with if you accept the misnomer.

In the default configuration, Javascript packs are saved in app/javascript/packs. An application.js file can be used to import Javascript libraries which are necessary throughout the application. Javascript files specific to a page can be placed in separate files, within the packs folder. For example, the packs folder might look like this

├── app
|   ├── javascript
|       ├── packs
|           ├── application.js
|           ├── hello.js

To import application.js throughout the app, add the pack to application.html.erb:

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

Webpack Entry Point

Webpack configuration is defined in config/webpacker.yml. This file defines the packs compiled by webpack. In the config file, the source_entry_path defines the folder automatically compiled by webpacker - the entry point webpacker will begin compiling your assets with the files in this folder.

source_path: app/javascript
source_entry_path: packs

If you configure Webpacker to compile your SCSS assets as well, you will end up placing CSS files in this folder. You may want to change the name of the folder to app/frontend or something which describes both javascript and CSS. If you do this, modify the source_path line of the webpacker.yml file. You will also want to change the link to the application stylesheet, within application.html.erb, from stylesheet_link_tag to stylesheet_pack_tag, since your stylesheets will now be compiled into a Webpacker pack.

<%= stylesheet_pack_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>

Plugins

The Webpack API has a ProvidePlugin function which automatically loads modules. To integrate a third-party Javascript library into your app, use ProvidePlugin within config/webpack/environment.js. For example, to include JQuery,

const { environment } = require("@rails/webpacker");

const webpack = require("webpack");
environment.plugins.prepend(
  "Provide",
  new webpack.ProvidePlugin({
    $: "jquery/src/jquery",
    jQuery: "jquery/src/jquery",
  })
);

module.exports = environment;

Further reading