Webpacker 6
Webpacker was officially retired before the official v6.0.0 was released following the release of Rails 7. Shakapacker is the official, actively maintained successor to Webpacker now.
Since the final version was never released, this post has been archived and will not receive further updates. The original upgrade guide was in multiple steps, but have been combined here for convenience.
Before we start the upgrade process for Webpacker 6, we are going to create a small demo application for us to work on.
If you are upgrading an existing app or not using this series as a tutorial, you can skip this step! We will begin the formal upgrade process in the next article.
Generate a new Rails app
First we will generate new Ruby on Rails app:
rails new webpacker_6 --skip-sprockets --skip-spring --skip-webpack-install --skip-bundlecd webpacker_6
--skip-sprockets
: Skip Sprockets files--skip-spring
: Don’t install Spring application preloader--skip-bundle
: Don’t run bundle install--skip-webpack-install
: Don’t run Webpack install
Setup the Database
bin/rails db:prepare
Turn off asset scaffolding
Prevent Rails from creating asset files when running the generators and scaffolds:
# config/application.rb # ...module Webpacker6 class Application < Rails::Application config.load_defaults 6.1+ config.generators do |g|+ g.assets false+ end endend
Add Pages Controller
Generate pages controller with a home action:
bin/rails g controller pages home
Add Root Route
Set pages#home
as the root route:
# config/routes.rb Rails.application.routes.draw do get 'pages/home'+ root to: 'pages#home' # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.htmlend
Note: Because we skipped the Webpacker install task, you will get an error if you try to start the application as is. We will fix that in the next article.
Updating our Gemfile
Update the gem in your Gemfile
:
# Gemfile - gem 'webpacker', '~> 5.0'+ gem 'webpacker', '~> 6.0.0.beta.2'
Next, run bundle install
to install the new gem version. If all goes well, you should see Using webpacker 6.0.0.beta.2 (was 5.2.1)
in the install output.
Installing in our Application
Run the installation command, bin/rails webpacker:install
, to generate the required configuration files, as well as update our package.json
Update Document Head
Lastly, let’s update app/views/layouts/application.html.erb
. The docs for Webpacker v6 recommend using the javascript_packs_with_chunks_tag
tag.
<%# app/views/layouts/application.html.erb %> - <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>- <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>+ <%= javascript_packs_with_chunks_tag 'application', 'data-turbolinks-track': 'reload' %>
Verify Installation
Run the Rails server (bin/rails s
) and the Webpack Dev Server (bin/webpack-dev-server
) via your preferred method. Two terminal tabs will work or create a Procfile and run via overmind or foreman. The Rails server will also compile your assets if the dev server is not running, but this is much slower vs running separate processes and not recommended.
Visit http://localhost:3000
in your browser. If all’s well, you should see the contents of app/views/pages/home.html.erb
.
We can verify our JavaScript is getting loaded by adding the following to app/javascript/packs/application.js
:
// app/javascript/packs/application.js console.log("Hello from Webpacker!")
Open the browser console and reload the page and you should see the message we added:
[Log] Hello from Webpacker! (application-7fbebc85af7886af0a64.js, line 62)
In order to process .css
files with Webpacker 6, you need to add css-loader, style-loader, and mini-css-extract-plugin.
Install
yarn add css-loader style-loader mini-css-extract-plugin
Usage
Add a stylesheet_packs_with_chunks_tag
or stylesheet_pack_tag
to the document head.
Make sure you restart bin/webpack-dev-server
after installing new loaders.
Style Loader Example
<%# app/views/layouts/application.html.erb %> + <%= stylesheet_packs_with_chunks_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %><%= javascript_packs_with_chunks_tag 'application', 'data-turbolinks-track': 'reload' %>
Extract Example
<%# app/views/layouts/application.html.erb %> <%= javascript_packs_with_chunks_tag 'application', 'data-turbolinks-track': 'reload' %>+ <%= stylesheet_pack_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
// app/javascript/packs/application.js + import "./application.css"
Verify
Note: Make sure you restart the dev server!
Let’s create a new file for our CSS:
touch app/javascript/packs/application.css
Next, add some CSS:
/* app/javascript/packs/application.css */ h1 { font-size: 2.2em; color: #2563eb;} p { font-size: 1.2em;}
Reload your browser and your styles should be applied now, and the Webpacker loader error should be gone.
In order to process .pcss
files with Webpacker 6, you need to add postcss-loader. I am also going to add PostCSS 8 support.
Install
yarn add postcss-loader postcss@latest autoprefixer@latest postcss-import@latest
Add PostCSS Config File
touch postcss.config.js
// postcss.config.js module.exports = { plugins: [ require('postcss-import'), require('autoprefixer') ]}
Usage
You should be able to use the same pack tag that you added for CSS.
Make sure you restart bin/webpack-dev-server
after installing new loaders.
Style Loader Example
<%# app/views/layouts/application.html.erb %> + <%= stylesheet_packs_with_chunks_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %><%= javascript_packs_with_chunks_tag 'application', 'data-turbolinks-track': 'reload' %>
Extract Example
<%# app/views/layouts/application.html.erb %> <%= javascript_packs_with_chunks_tag 'application', 'data-turbolinks-track': 'reload' %>+ <%= stylesheet_pack_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
// app/javascript/packs/application.js + import "./application.css"
Verify
Note: Make sure you restart the dev server!
Let’s create a new PostCSS file:
mkdir app/javascript/stylesheetstouch app/javascript/stylesheets/base.pcss
Next, add some CSS:
/* app/javascript/stylesheets/base.pcss */ h1 { font-size: 2.2em; color: #2563eb;} p { font-size: 1.2em;}
Lastly, update application.css
:
/* app/javascript/packs/application.css */ @import "../stylesheets/base.pcss";
Reload your browser and your styles should be applied now, and the Webpacker loader error should be gone.
In order to process .scss
and .sass
files with Webpacker 6, you need to add sass-loader and sass.
Note: This section builds on the CSS section
Install
yarn add sass-loader sass
Usage
You should be able to use the same pack tag that you added for CSS.
Make sure you restart bin/webpack-dev-server
after installing new loaders.
Style Loader Example
<%# app/views/layouts/application.html.erb %> + <%= stylesheet_packs_with_chunks_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %><%= javascript_packs_with_chunks_tag 'application', 'data-turbolinks-track': 'reload' %>
Extract Example
<%# app/views/layouts/application.html.erb %> <%= javascript_packs_with_chunks_tag 'application', 'data-turbolinks-track': 'reload' %>+ <%= stylesheet_pack_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
// app/javascript/packs/application.js + import "./application.scss"
Verify
Note: Make sure you restart the dev server!
Let’s create a new SCSS file:
touch app/javascript/packs/application.scss
Next, add some SCSS:
/* app/javascript/packs/application.scss */ $body-background: #fafafa;$body-color: #444; body { background: $body-background; color: $body-color; font-family: sans-serif;} h1,nav,footer { text-align: center;} main { margin: 4rem auto; max-width: 60rem;}
Reload your browser and your styles should be applied now, and the Webpacker loader error should be gone.
In order to use your images and SVG files with Webpacker 6, you need to put them in the correct place and import them into your context.
Install
We should be good here.
Usage
Add Assets
mkdir -p app/javascript/media/images
Require Context
// app/javascript/packs/application.js++ function importAll(r) {+ r.keys().forEach(r);+ }+ // Add relevant file extensions as needed below.+ // I'm sure there is a better way :shrug:+ importAll(require.context('../media/images/', true, /\.(svg|jpg)$/));
Verify
Note: Restart the dev server for good luck!
Add an SVG and PNG into app/javascript/media/images
In one of your views, add two image tags:
<img src="<%= asset_pack_path 'media/images/icon.svg' %>" /><img src="<%= asset_pack_path 'media/images/surf.jpg' %>" />
Reload your browser and you should see your images.
Note that <%= asset_pack_path 'media/images/icon.svg' %>
only returns a string, so if you would rather inline your SVG files you will need to refer to the Webpack Asset Modules documentation and merge your changes into your Webpack context, as explained in these Webpacker docs.
Hey, I'm Andrew 👋
I'm a senior product engineer at Podia, co-host of Remote Ruby and Ruby for All, and co-editor of Ruby Radar. You can explore my writing, learn more about me, or subscribe to my RSS feed.