DEV Community

Ayush Newatia
Ayush Newatia

Posted on • Updated on

How to autoload Stimulus within every controller file

If you're familiar with Stimulus at all, the below bog standard controller should look very familiar. In fact I've nicked it from their homepage!

import { Controller } from "stimulus"

export default class extends Controller {
  static targets = ["name", "output"]

  greet() {
    this.outputTarget.textContent =
      `Hello, ${this.nameTarget.value}!`
  }
}
Enter fullscreen mode Exit fullscreen mode

I'm a Rubyist and unashamedly rather lazy; so having that import statement at the top of every Stimulus controller always irked me. If you're using Webpack, there's a super simple way of circumventing this annoying import statement.

First thing you need to do is create a file called application_controller.js and place it in your controllers directory. This is good practice nevertheless as you can put app specific utilities in there; such as getting some data out of meta tags for example.

// application_controller.js
import { Controller } from 'stimulus'

export default class extends Controller {
}
Enter fullscreen mode Exit fullscreen mode

And then change your controllers to inherit from ApplicationController and remove the import statement. So the above controller would become:

export default class extends ApplicationController {
  static targets = ["name", "output"]

  greet() {
    this.outputTarget.textContent =
      `Hello, ${this.nameTarget.value}!`
  }
}
Enter fullscreen mode Exit fullscreen mode

And finally we need to make a change to our Webpack configuration so the controllers know where to find ApplicationController without the import statement. We'll use the Webpack Provide plugin to accomplish this.

Add the following lines to the plugins array in your webpack.config.js:

new webpack.ProvidePlugin({
  ApplicationController: ['./application_controller', 'default']
})
Enter fullscreen mode Exit fullscreen mode

If you're using Webpacker 5 or older, add the following lines to your config/webpack/environment.js:

const webpack = require('webpack')

environment.plugins.append('Provide', new webpack.ProvidePlugin({
  ApplicationController: ['./application_controller', 'default']
}))
Enter fullscreen mode Exit fullscreen mode

And if you're using Webpacker 6, change your config/webpack/base.js to:

const { webpackConfig, merge } = require('@rails/webpacker')
const webpack = require('webpack')

const customConfig = {
  plugins: [
    new webpack.ProvidePlugin({
      ApplicationController: ['./application_controller', 'default']
    })
  ]
}

module.exports = merge(webpackConfig, customConfig)
Enter fullscreen mode Exit fullscreen mode

And that should do the trick! You no longer need to import Controller manually within every Stimulus controller!

Shout out to Konnor Rogers for showing me how to do this :)

This post was originally published on my blog

Top comments (0)