I'm working on a personal development application with Rails7+Tailwind, and I implemented the code to delete flash messages in stimulus with reference to a web article.
I'm having trouble solving the problem that Stimulus (erasing Flash messages) that was running on Local doesn't work when deployed on Heroku.
Codes of the part related to the following, so If you have any doubts, please let me know.
Development environment.
Rails 7.0.2.4.
ruby 3.1.2p20
Error messages on heroku logs is as followings.
2022-06-02T07:51:13.858354+00:00 app[web.1]: F, [2022-06-02T07:51:13.858304 #4] FATAL -- : [a7811503-f91a-4d6e-9a5d-978744f7129b]
2022-06-02T07:51:13.858355+00:00 app[web.1]: [a7811503-f91a-4d6e-9a5d-978744f7129b] ActionController::RoutingError (No route matches [GET] "/assets/controllers/flash_controller.js"):
app/views/layouts/application.html.erb
is as followings.
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
<%= stylesheet_link_tag "tailwind", "inter-font", "data-turbo-track": "reload" %>
<%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
<%= javascript_importmap_tags %>
<%= render 'layouts/shim' %>
<title><%= page_title(yield(:title)) %></title>
</head>
<body class="pb-420 box-border">
<main>
<%= render 'shared/navbar' %>
<%= render partial: 'shared/flash' %>
<div class="w-full">
<%= yield %>
<%= render 'shared/footer' %>
</div>
</main>
</body>
</html>
Where the part which is used stimulus.
<% flash.each do |key, value| %>
<div data-controller="flash" class="flex items-center fixed top-5 right-5 <%= css_class_for_flash(key) %> py-3 px-5 rounded-lg">
<div class="mr-4"><%= value %></div>
<button type="button" data-action="flash#dismiss">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
</div>
<% end %>
app/javascript/controllers/flash_controller.js
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
connect() {
setTimeout(() => {
this.dismiss();
}, 3000);
}
dismiss() {
this.element.remove();
}
}
app/javascript/controller/index.js
import { application } from "./application"
import FlashController from "./flash_controller.js"
application.register("flash", FlashController)
As commented by appleII717, the cause was that the folder structure used esbuild even though importmap was used.
The reference source which I copied the code of stimulus is using esbuild, but I have not noticed about that.
By modifying the folder configuration for importmap, stimulus now works even in heroku environment!
app/javascript/controller/index.js
// Import and register all your controllers from the importmap under controllers/*
import { application } from "controllers/application"
// Eager load all controllers defined in the import map under controllers/**/*_controller
import { eagerLoadControllersFrom } from "@hotwired/stimulus-loading"
eagerLoadControllersFrom("controllers", application)