map7
map7

Reputation: 5126

Rails 6.1 stimulus not loading with asset pipeline

I've got a large app written in Rails 6.1 which is still using the asset pipeline. I'm trying to convert it from using AngularJS (which is stored in the asset pipeline) to hotwire-rails. I've got turbo loaded and now I would like to get Stimulus working.

It's on Ruby 2.7.4 and I'm using the latest importmaps-rails (0.8.2), turbo-rails (0.8.3) and stimulus-rails (0.7.2).

I've done a rails stimulus:install and rails importmap:install and when I reload my app and test with trying to use the hello_controller stimulus doesn't run, I'm stuck with 'foo' on the screen instead of "Hello World!"

I've got this test in my view

<div data-controller="hello">
  foo
</div>

app/javascript/controller/hello_controller.js

import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  connect() {
    this.element.textContent = "Hello World!"
  }
}

Gemfile;

gem 'importmap-rails',
gem 'hotwire-rails'
gem 'turbo-rails'
gem 'stimulus-rails'

Here is my application_html.erb file I'm loading for the separate hotwire views

<!DOCTYPE html>
<html>
  <head>
    <title></title>
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

    <%= stylesheet_link_tag 'application_html' %>
    <%= javascript_include_tag "application_html" %>
    <%= turbo_include_tags %>
    <%= javascript_include_tag "turbo", type: "module-shim" %>
    <%= javascript_importmap_tags %>
  </head>
  <body>
    <%= yield :javascript %>
    <%= yield %>
  </body>
</html>

config/importmap.rb

pin "application", preload: true
pin "@hotwired/stimulus", to: "stimulus.js", preload: true
pin "@hotwired/stimulus-loading", to: "stimulus-loading.js", preload: true
pin_all_from "app/javascript/controllers", under: "controllers"
pin "@hotwired/turbo-rails", to: "turbo.js"

app/javascript/application.js

import "controllers"
import "@hotwired/turbo-rails"

app/javascript/controllers/application.js

import { Application } from "@hotwired/stimulus"

const application = Application.start()

// Configure Stimulus development experience
application.warnings = true
application.debug    = false
window.Stimulus      = application

export { application }

Update

If I remove the following from my application_html.html.erb file then turbo stops working.

<%= javascript_include_tag "application_html" %>
<%= turbo_include_tags %>
<%= javascript_include_tag "turbo", type: "module-shim" %>

Update

Further debugging leads to me thinking my importmap-rails is not loading correctly.

Upvotes: 2

Views: 2803

Answers (2)

RyanW
RyanW

Reputation: 5398

Found this questions when researching a similar problem while adding hotwire/stimulus/importmap to a Rails 6 app. This was the error I was getting

Sprockets::Rails::Helper::AssetNotPrecompiledError

Asset was not declared to be precompiled in production.
Add `Rails.application.config.assets.precompile += %w( controllers/hello_controller.js )` to `config/initializers/assets.rb` and restart your server

After going through the steps outlined in map7's answer, the error was still happening. Finally discovered that sprockets was on version 3.7. After upgrading to sprockets 4, the error went away and importmap started working.

Upvotes: 1

map7
map7

Reputation: 5126

Solved my problem after I created a new rails app without webpack and tried getting importmap and asset pipeline javascript to work at the same time.

I found that my problems with my legacy project were;

  1. I was missing manifest.js

             //= link_tree ../images
             //= link_directory ../stylesheets .css
             //= link_tree ../../javascript .js
             //= link_tree ../../../vendor/javascript .js
             //= link_tree ../javascripts .js
    
  2. Rename application.js in asset pipeline to application_angularjs.js

            cd app/assets/javascripts
            mv application.js application_angularjs.js
    
  3. Change line in application.html.erb (from, to)

    From

    <%= javascript_include_tag "application" %>
    

    To

    <%= javascript_include_tag "application_angularjs" %>
    
  4. Remove extra lines in application_html.erb

    <%= turbo_include_tags %>
    <%= javascript_include_tag "turbo", type: "module-shim" %>
    

After this it all came to life, importmap started working and so did my stimulus hello controller example.

Upvotes: 3

Related Questions