You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails7部署Heroku后Stimulus Flash消息功能失效 报JS资产路由错误

Rails7+Tailwind部署Heroku后Stimulus Flash功能失效排查

问题现象

  • 技术栈版本:Rails 7.0.2.4、Ruby 3.1.2p20、Tailwind CSS
  • 功能逻辑:通过Stimulus实现Flash消息3秒自动消失、点击按钮手动关闭功能,本地开发环境运行完全正常,部署到Heroku后功能全部失效
  • Heroku日志核心报错:
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"):

报错本质:生产环境无法找到编译后的flash_controller.js资产文件,Stimulus控制器未正常加载注册

现有相关代码

1. 全局布局文件 app/views/layouts/application.html.erb

<!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>

2. Flash消息渲染模板

<% 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 %>

3. Stimulus Flash控制器 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();
  }
}

4. Stimulus控制器注册文件

当前文件存放路径:app/javascript/controller/index.js(注意目录名为单数形式)

import { application } from "./application"

import FlashController from "./flash_controller.js"
application.register("flash", FlashController)

修复方案

按优先级依次排查修复:

  1. 修正目录命名错误
    当前Stimulus控制器注册入口index.js放在了单数命名的app/javascript/controller/目录下,而Rails + Stimulus默认的资产扫描、控制器加载路径是复数命名的app/javascript/controllers/目录。本地开发环境资产加载规则宽松,会递归扫描javascript目录下的所有js文件,所以功能正常;但生产环境资产预编译只会加载标准路径下的入口文件,导致注册逻辑根本没被执行,浏览器只能直接请求裸的控制器文件路径触发404。
    操作:把app/javascript/controller/index.js移动到app/javascript/controllers/index.js路径下,和flash_controller.js、application.js放在同一目录。
  2. 更新importmap映射配置
    因为之前入口文件路径错误,importmap没有正确收录自定义Stimulus控制器的资产路径,本地项目根目录执行以下命令,自动把所有自定义控制器的路径写入importmap配置:
    bin/importmap pin app/javascript/controllers/**/*.js
    
    执行完成后检查config/importmap.rb文件,确认存在flash_controller相关的pin配置即可。
  3. 重新部署验证
    把上述修改提交到Git仓库,重新推送到Heroku触发部署,部署日志中确认出现Asset precompilation completed相关提示,代表资产已经正确编译。部署完成后访问页面,Flash消息的自动消失、手动关闭功能即可恢复正常,不会再出现js文件404的报错。

内容的提问来源于stack exchange,提问作者mojaomi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 09:36:20