shou2017.com
JP

Using stimulus.js with Rails

Thu Feb 21, 2019
Sat Aug 10, 2024

Environment

  • macOS Mojave 10.14.3
  • Rails 5.2.2
  • ruby 2.6.1

What is Stimulus

Stimulus is a JavaScript framework developed by the Basecamp team, well-known for Rails. It has good compatibility with Rails and can coexist with turbolinks.

It’s a perfect JavaScript framework for small development teams or individual developers who don’t have dedicated front-end engineers.

Official Documentation

Getting Started

To manage gems on a per-project basis, do the following:

$ mkdir stimulus
$ cd stimulus
$ bundle init

Edit the Gemfile:

# frozen_string_literal: true

source "https://rubygems.org"

git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }

# gem "rails"

gem 'rails', '~> 5.2.2'

Next, run bundle install --path vendor/bundle. In subsequent runs, --path vendor/bundle is not needed.

$ bundle install --path vendor/bundle

Rails new

Although you can install stimulus with rails new --webpack=stimulus, I chose to install stimulus afterwards because I had trouble fixing webpack configuration errors.

$ bundle exec rails new . -B -d postgresql  --skip-coffee
$ bundle exec rails db:create
$ bundle exec rails s

If you get the following error after bundle exec rails db:create:

Could not find gem 'pg (>= 0.18, < 2.0)' in any of the gem sources listed in your Gemfile.

$ brew uninstall postgresql
$ brew install postgresql
$ bundle install --path vendor/bundle

Installing Webpacker gem

Install the Webpacker gem. Add the following line to your Gemfile and run bundle install. I’m specifying the version here because gem 'webpacker', github: 'rails/webpacker' would install version 4 which caused errors.

# Gemfile
gem 'webpacker', '~> 3.5'

Run bin/rails webpacker:install. Make sure to install Yarn beforehand if you don’t have it.

$ bin/rails webpacker:install

Installing Stimulus

$ bundle exec rails webpacker:install:stimulus

After completing these steps, your app/javascripts/packs/application.js should look like this:

# app/javascripts/packs/application.js
/* eslint no-console:0 */
// This file is automatically compiled by Webpack, along with any other files
// present in this directory. You're encouraged to place your actual application logic in
// a relevant structure within app/javascript and only use these pack files to reference
// that code so it'll be compiled.
//
// To reference this file, add <%= javascript_pack_tag 'application' %> to the appropriate
// layout file, like app/views/layouts/application.html.erb
console.log('Hello World from Webpacker')

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

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

Next, add <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %> to your views/layouts/application.html.erb.

Reference: webpacker

Reference: stimulus Handbook

# views/layouts/application.html.erb

<!DOCTYPE html>
<html>
  <head>
    <title>Stimulus</title>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

    <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
    <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
  </head>

  <body>
    <%= yield %>
  </body>
</html>

This completes the stimulus configuration.

Creating a hello stimulus example

$ rails g controller Hello index

View:

# views/hello/index.html.erb

<h1>Hello#index</h1>
<p>Find me in app/views/hello/index.html.erb</p>

<div data-controller="hello">
  <h1 data-target="hello.output"></h1>
</div>

Next, create hello_controller.js in the following directory:

app/javascripts/packs/controllers/hello_controller.js

// app/javascripts/packs/controllers/hello_controller.js

import { Controller } from "stimulus"
export default class extends Controller {
  static targets = [ "output" ]
  connect() {
    this.outputTarget.textContent = 'Hello, Stimulus!'
  }
}

Using stimulus.js with Rails

強いチームはオフィスを捨てる: 37シグナルズが考える「働き方革命」

See Also