Home > database >  Rails 7: Loading all Stimulus controllers
Rails 7: Loading all Stimulus controllers

Time:04-17

I've recently upgraded my app from Rails 6 to Rails 7, but some items seem to have changed with how Stimulus controllers are loaded from javascript/controllers.

I Rails 6 I was able to do this from an index.js file in the javascript/controllers directory:

const context = require.context("controllers", true, /_controller\.js$/)
application.load(definitionsFromContext(context))

However in Rails 7 this raises (in my browsers js console):

Uncaught TypeError: __require.context is not a function

So I'm stuck calling this for each of my Stimulus controllers:

import FooBarController from "./foo_bar_controller"
application.register("foo_bar_controller", FooBarController)

What is the right way to import and register all my Stimulus controllers in Rails 7? I cannot find any details on this in the docs.

UPDATE:

I ran the stimulus:install rake task, and it did change some of my files that I had that were previously incorrect. However now when I build the app I get this:

✘ [ERROR] Could not resolve "controllers/application"
    app/javascript/controllers/index.js:3:28:
      3 │ import { application } from "controllers/application"
        ╵                             ~~~~~~~~~~~~~~~~~~~~~~~~~
  You can mark the path "controllers/application" as external to exclude it from the bundle, which will remove this error.
✘ [ERROR] Could not resolve "@hotwired/stimulus-loading"
    app/javascript/controllers/index.js:6:41:
      6 │ import { eagerLoadControllersFrom } from "@hotwired/stimulus-loading"
        ╵                                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  You can mark the path "@hotwired/stimulus-loading" as external to exclude it from the bundle, which will remove this error.

This is what I have in my importmap.rb file as well:

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"

CodePudding user response:

This depends on what you're currently using as a JavaScript bundler/builder.

The Stimulus Handbook explains the different methods of installation and autoloading controllers in Rails.

require.context was only available through webpack. This has been replaced with Hotwire Stimulus in Rails 7 (and optionally importmap).

It sounds like you're currently on esbuild, so you should be able to update the index.js controller imports using the command rails stimulus:manifest:update.

This may require that you run rails stimulus:install first.

  • Related