Yurii Stefaniuk
Yurii Stefaniuk

Reputation: 1797

How automatically load all js controller files in Rails 7 with esbuild as JavaScript bundler

I'm trying to configure Rails 7 app to load all js Stimulus controllers automatically.

I use esbuild as JavaScript bundler.

If we're using Stimulus for Rails together with an import map, the integration will automatically load all controller files from app/javascript/controllers.

// app/javascript/controllers/index.js

import { application } from "controllers/application"

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

This @hotwired/stimulus-loading package comes from importmap

# config/importmap.rb

pin "@hotwired/stimulus-loading", to: "stimulus-loading.js", preload: true

But it looks like @hotwired/stimulus-loading has not been published to NPM yet and is meant to be used only with importmaps in Rails.

When we're using Webpacker as JavaScript bundler we can use @hotwired/stimulus-webpack-helpers package to get the same form of autoloading behavior.

// app/javascript/application.js

import { Application } from "@hotwired/stimulus"
import { definitionsFromContext } from "@hotwired/stimulus-webpack-helpers"

window.Stimulus = Application.start()
const context = require.context("./controllers", true, /\.js$/)
Stimulus.load(definitionsFromContext(context))

But when we're using esbuild JavaScript bundler on the official Stimulus page recommended to import each controller individually.

Stimulus works with other build systems too, but without support for controller autoloading. Instead, you must explicitly load and register controller files with your application instance:

// app/javascript/application.js

import { Application } from "@hotwired/stimulus"

import HelloController from "./controllers/hello_controller"
import ClipboardController from "./controllers/clipboard_controller"

window.Stimulus = Application.start()
Stimulus.register("hello", HelloController)
Stimulus.register("clipboard", ClipboardController)

So my question is:

Is it possible to configure Rails 7 with esbuild as JavaScript bundler to load all js Stimulus controller files from app/javascript/controllers automatically?

Upvotes: 2

Views: 2172

Answers (1)

Thomas Van Holder
Thomas Van Holder

Reputation: 1507

Manually running a task to include all stimulus controllers

To include a new stimulus controller that you manually created in the app/javascript/controllers/index.js file, you can run:

rails stimulus:manifest:update

Automatically including a newly created stimulus controller

When you create a stimulus controller from the terminal with the generator, rails will automatically run the manifest:update command and so include your controller in js build.

rails generate stimulus controllerName

Watching for live file changes to stimulus controllers

To watch for live changes to your stimulus controllers, an additional watch process is needed. This additional watch process is appended to the Procfile.dev file after installing esbuild.

# Procfilde.dev

web: rails s -p 3000
css: yarn build:css --watch
js: yarn build --watch

The yarn build --watch command triggers the build command specified in the packacke.json file.

{
  "name": "myapplication",
  "scripts": {
    "build": "esbuild app/javascript/*.* --bundle --outdir=app/assets/builds"
   }
}

Upvotes: 4

Related Questions