Propshaft + StimulusJS + Importmaps

I’m a bit confused because this seems like a pretty straightforward pattern, but I can’t find any documentation around it.

I’m trying to upgrade my app to Rails 8, and hence switch out sprockets for propshaft. I have the following setup:

app
|-> javascript
  |-> application.js 
       controllers
        |-> index.js
             some_other_controller.js

application.js:

// ...
import "controllers"
// ...

controllers/index.js:

import { application } from "controllers/application"
import { eagerLoadControllersFrom } from "@hotwired/stimulus-loading"
eagerLoadControllersFrom("controllers", application)

importmap.rb:

pin 'application', 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'

This seems to work OK, except that Stimulus “eager load controllers” is trying to load “assets/controllers/some_other_controller” instead of “controllers/some_other_controller” (which is what the importmap outputs). Part of the importmap output:

    "controllers": "/assets/controllers/index-ee64e1f1.js",
    "controllers/some_other_controller": "/assets/controllers/some_other_controller-968b6939.js",

and the error: GET http://localhost:3000/assets/controllers/some_other_controller net::ERR_ABORTED 404 (Not Found)

Any idea how to get these things to play well together?

3 Likes

Btw I’ve compared the outputs of Sprockets and Propshaft and the actual HTML file looks the same. So there must be something about how Propshaft is serving these files.

1 Like

I have the exact same issue. Did you find any solution to this?

@reinvanimschoot we managed to solve it with the below changes, hope that will help others face the same issue

  • in the application.rb disabled → config.assets.enabled = false [if you are using sprockets before ]
  • if importing some_other_controller in ur application.js that way “import SomeOtherController from "./some_other_controller” and u have the above structure change it to “import SomeOtherController from "controllers/some_other_controller
  • make sure you recompile your assets after changes

thats because propshaft will create all javascript files under the assets directory to be under public directory after adding to them the fingureprint so there relative path will be different assets/controllers/some_other_controler.js

1 Like