There are few things to set up to make webpacker work with Rails 6.
Following work with Rails 6.1.0.alpha 526dd64
& Webpacker 4.2.2.
This file must be present per sprockets-rails#444.
{}
sprockets-rails#446 to make this an option so you can put in other places.
Comment/remove require of sprockets railtie in config/application.rb
:
-require "sprockets/railtie"
+# require "sprockets/railtie"
Comment/remove all occurrences related to config.assets
in development.rb
and production.rb
.
I recommend to have a app/webpacker
directory (because we are going to have JS, CSS, assets files in this directory. Rails's default app/javascript
seems weird, but you can choose not to fight with the framework). You need to tell Webpacker to find files in app/webpacker
and turn on emits CSS.
# config/webpacker.yml
default: &default
source_path: app/webpacker # app/javascript/ (default)
# ...
# Extract and emit a css file
extract_css: true
With subdirectory of javascripts
, packs
, and stylesheets
.
app
├── assets
│ └── config
│ └── manifest.js
└── webpacker
├── images
│ └── logo.svg
├── javascripts
│ └── application.js
├── packs
│ └── application.js
└── stylesheets
└── application.scss
webpacker/packs/application.js
will be the entry point to interact with Webpacker:
import 'javascripts/application'
import 'stylesheets/application'
This will import webpacker/javascripts/application.js
and webpacker/stylesheets/application.scss
.
webpacker/images
will be the place to put images.
webpacker/javascripts
will be the place to put JavaScript.
webpacker/stylesheets
will be the place to put CSS.
webpacker/javascripts/application.js
will be the entry to import all the JavaScripts (same role as good old app/assets/javascripts/application.js
).
We can still have modular JavaScript (e.g. cable.js
) and import it:
import "./cable"
webpacker/stylesheets/application.scss
will be the entry to import all your stylesheets (same role as good old app/assets/stylesheets/application.scss
).
We can still have modular css (e.g. _root.scss
) and import it:
// webpacker/stylesheets/application.scss
import "root";
webpacker/images/
will be the directory to put all the images (same role as good old app/assets/images/
).
Add the following to packs/application.js
to import all images:
const imageContext = require.context('images/', true)
imageContext.keys().forEach(imageContext)
Reference your image with asset_pack_path
helper in the view.
$ yarn add rails-ujs
Add following to webpacker/javascripts/application.js
:
import Rails from "rails-ujs"
Rails.start()
$ yarn add turbolinks
Add following to webpacker/javascripts/application.js
:
import Turbolinks from "turbolinks"
Turbolinks.start()
$ yarn add activestorage
Add following to webpacker/javascripts/application.js
:
import * as ActiveStorage from "activestorage"
ActiveStorage.start()
$ yarn add actioncable
Add following to webpacker/javascripts/application.js
:
// app/webpacker/javascripts/cable.js
import cable from 'actioncable'
window.App || (window.App = {})
window.App.cable = cable.createConsumer()
const context = require.context('./channels', true, /_channel\.js$/)
context.keys().forEach(context)
And put each JavaScript file (with suffix of _channel.js
) for channel in webpacker/javascripts/channels
folder.
$ yarn add stimulus
Put Stimulus controller files under webpacker/javascripts/controllers/
and the following to webpacker/javascripts/application.js
to import them:
import { Application } from "stimulus"
import { definitionsFromContext } from "stimulus/webpack-helpers"
const application = Application.start()
const context = require.context("./controllers", true, /\.js$/)
application.load(definitionsFromContext(context))
Use the new *_pack_tag
in the layout:
<%= stylesheet_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload', defer: true %>
There is also asset_pack_path
:
<img src="<%= asset_pack_path('images/logo.svg') %>">
Besides rails s
, have another terminal tab with bin/webpack-dev-server
. Webpacker automatically refresh your page and tell you if something went wrong during compliation of your front-end files. You can also use foreman to start both rails and webpack-dev-server.
That’s it!