Mature app updating to Rails 7.0.7, Ruby 3.1.2, adding stimulus-rails
using the installer, with importmap-rails
, turbo-rails
and sprockets-rails
already installed. No custom Stimulus controllers yet, just trying to load the setup "out of the box".
I've read through a dozen Q/A's about this on StackOverflow, including Alex's lengthy and good explanations of how importmap-rails
works, but none of them seem to explain this case.
When I boot the server locally, i'm getting
ActionController::RoutingError (No route matches [GET] "/stimulus-loading.js"):
Everything seems right in the importmap:
Here is the result of ./bin/importmap json
:
{
"imports": {
"application": "/assets/application.js",
"@rails/ujs": "/assets/@rails--ujs.js",
"@hotwired/turbo-rails": "/assets/turbo.min.js",
"@hotwired/stimulus": "/assets/stimulus.min.js",
"@hotwired/stimulus-loading": "/assets/stimulus-loading.js",
"controllers/application": "/assets/controllers/application.js",
"controllers/hello_controller": "/assets/controllers/hello_controller.js",
"controllers": "/assets/controllers/index.js"
}
}
I have run rails assets:clobber
as suggested in several answers. Here's the standard setup, these lines all added by the installers for turbo-rails
, importmap-rails
and stimulus-rails
gems.
# config/importmap.rb
pin "application", preload: true
pin "@rails/ujs", to: "@rails--ujs.js" # @7.0.7
pin "@hotwired/turbo-rails", to: "turbo.min.js", preload: true
pin "@hotwired/stimulus", to: "stimulus.min.js", preload: true
pin "@hotwired/stimulus-loading", to: "stimulus-loading.js", preload: true
pin_all_from "app/javascript/controllers", under: "controllers"
# application.js
import "@hotwired/turbo-rails"
import Rails from "@rails/ujs"
import "@hotwired/stimulus"
import "@hotwired/stimulus-loading"
Rails.start(); import "controllers"
Here's my assets/config/manifest.js
//= link_tree ../images
//= link_tree ../javascripts .js
//= link_tree ../../javascript .js
//= link_tree ../../../vendor/javascript .js
//= link my_application.js
I renamed app/assets/javascripts/my_application.js
to avoid naming conflict with app/javascript/application.js
I've added app/javascript
to the asset path (didn't seem to change anything)
# config/initializers/assets.rb
Rails.application.config.assets.paths << Rails.root.join("app/javascript")
I've added asset debugging and tried turning on/off compiling
# config/environments/development
config.assets.compile = true # if false, no assets found
config.assets.debug = true # didn't tell me anything new
Log of page load in dev mode:
Started GET "/assets/es-module-shims.min.js" for 10.0.2.2 at 2023-09-06 16:47:39 +0000
10.0.2.2 - - [06/Sep/2023:16:47:38 UTC] "GET /assets/es-module-shims.min.js HTTP/1.1" 304 0
http://localhost:3000 -> /assets/es-module-shims.min.js
Started GET "/assets/BlackOnWhite.css" for 10.0.2.2 at 2023-09-06 16:47:40 +0000
Started GET "/assets/my_application.js" for 10.0.2.2 at 2023-09-06 16:47:41 +0000
10.0.2.2 - - [06/Sep/2023:16:47:38 UTC] "GET /assets/mo_application.js HTTP/1.1" 304 0
http://localhost:3000 -> /assets/mo_application.js
10.0.2.2 - - [06/Sep/2023:16:47:38 UTC] "GET /assets/BlackOnWhite.css HTTP/1.1" 304 0
http://localhost:3000 -> /assets/BlackOnWhite.css
Started GET "/assets/application.js" for 10.0.2.2 at 2023-09-06 16:47:42 +0000
10.0.2.2 - - [06/Sep/2023:16:47:42 UTC] "GET /assets/application.js HTTP/1.1" 200 367
http://localhost:3000 -> /assets/application.js
Started GET "/assets/stimulus.min.js" for 10.0.2.2 at 2023-09-06 16:47:44 +0000
Started GET "/assets/controllers/index.js" for 10.0.2.2 at 2023-09-06 16:47:44 +0000
Started GET "/assets/turbo.min.js" for 10.0.2.2 at 2023-09-06 16:47:45 +0000
10.0.2.2 - - [06/Sep/2023:16:47:43 UTC] "GET /assets/stimulus.min.js HTTP/1.1" 304 0
http://localhost:3000 -> /assets/stimulus.min.js
Started GET "/assets/stimulus-loading.js" for 10.0.2.2 at 2023-09-06 16:47:46 +0000
10.0.2.2 - - [06/Sep/2023:16:47:43 UTC] "GET /assets/turbo.min.js HTTP/1.1" 304 0
http://localhost:3000 -> /assets/turbo.min.js
ActionController::RoutingError (No route matches [GET] "/stimulus-loading.js"):
10.0.2.2 - - [06/Sep/2023:16:47:43 UTC] "GET /assets/stimulus-loading.js HTTP/1.1" 404 0
http://localhost:3000 -> /assets/stimulus-loading.js
10.0.2.2 - - [06/Sep/2023:16:47:43 UTC] "GET /assets/controllers/index.js HTTP/1.1" 304 0
http://localhost:3000-> /assets/controllers/index.js
It seems from the log that there may be a path discrepancy between /assets/stimulus-loading.js
and /stimulus-loading.js
. But the browser is showing a 404 for http://localhost:3000/assets/stimulus-loading.js
.
Solved.
Occurred to me to check issues on the stimulus-rails github page, and this is a known current issue, related to a current Sprockets issue with 4.1.1 where the hyphen in the name "stimulus-loading.js" makes Sprockets skip it because it thinks it's a digest.
The solution is setting config.assets.digest = true
in config/environments/development.rb
. According to the linked Stimulus issue, this is the Rails team's preferred setting for development, but it's been off in my legacy app since before my time.