Rails安装webpacker后无法识别执行JavaScript代码问题
Rails toastr消息失效、Webpacker目录异常修复方案
问题表现
- 开发Instagram克隆Rails项目时,使用
toastr-rails实现flash消息提示,布局文件内联script标签内的ERB代码未被解析,对应JS逻辑无法执行 - 安装Webpacker及对应gem后,
app/javascript路径下未自动生成packs目录,手动创建后应用仍无法识别普通JS代码、.js.erb后缀文件
问题涉及的app/views/layouts/application.html.erb原始代码:
<!DOCTYPE html> <html> <head> <title>Instagram</title> <meta name="viewport" content="width=device-width,initial-scale=1"> <%= csrf_meta_tags %> <%= csp_meta_tag %> <%= stylesheet_link_tag "application", "data-turbo-track": "reload" %> <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %> <script src="https://kit.fontawesome.com/5238639648.js" crossorigin="anonymous"></script> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css"> <!-- jQuery library --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script> <!-- Latest compiled JavaScript --> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script> </head> <body> <%= render 'shared/navbar' if current_user %> <div class="container"> <%= yield %> </div> <% if flash.any? %> <script type="text/javascript"> <% flash.each do |key, value| %> <% type = key.to_s.gsub('alert', 'error').gsub('notice', 'success') %> toastr.<%= type %>('<%= value %>') <% end %> </script> <% end %> </body> </html>
修复步骤
1. 补全Webpacker初始化流程
packs目录未自动生成是Webpacker安装未完成导致,手动创建目录不会生成配套编译规则,执行以下命令完成初始化:
bundle exec rails webpacker:install
命令执行完成后会自动生成标准目录结构:
- 自动创建
app/javascript/packs目录,生成入口文件application.js - 自动配置JS、ERB、样式文件的编译规则,原生支持
.js.erb后缀文件解析
2. 统一配置前端依赖
零散在布局文件中引入jQuery、toastr等资源会导致依赖加载顺序冲突,统一在Webpacker入口中管理依赖:
- 确认
toastr-rails已写入Gemfile,执行bundle install完成安装 - 编辑
app/javascript/packs/application.js,在文件顶部添加依赖引入与全局挂载代码:
// 挂载jQuery全局变量(toastr运行依赖jQuery) import $ from 'jquery' global.$ = $ global.jQuery = $ // 挂载toastr全局变量 import toastr from 'toastr' global.toastr = toastr // 引入toastr默认样式 import 'toastr/build/toastr.min.css'
- 移除其他位置重复的toastr、jQuery引入代码,避免变量冲突。
3. 修复内联脚本执行异常
内联toastr代码不执行的核心原因是脚本加载顺序错误、Turbolinks/Turbo渲染机制冲突,按以下规则调整布局文件:
- 将
javascript_pack_tag引用从head区域移到body标签最末尾,确保DOM加载完成、依赖挂载完成后再执行业务逻辑 - 对输出到JS字符串的flash内容使用
escape_javascript(别名j)做转义,避免内容包含单引号、特殊字符时触发JS语法错误 - 调整后的body区域代码参考:
<body> <%= render 'shared/navbar' if current_user %> <div class="container"> <%= yield %> </div> <% if flash.any? %> <script type="text/javascript"> <% flash.each do |key, value| %> <% type = key.to_s.gsub('alert', 'error').gsub('notice', 'success') %> const flashMsg = '<%= j value %>' toastr.<%= type %>(flashMsg) <% end %> </script> <% end %> <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %> </body>
如果项目启用了Turbo/Turbolinks,需额外将toastr触发逻辑绑定到页面加载完成事件,避免无刷新跳转时flash消息不触发
4. 验证配置
执行资源预编译命令,重启Rails服务后验证功能:
bundle exec rails webpacker:compile
排查技巧:打开浏览器开发者工具Console面板,若出现
toastr is not defined、$ is not defined类报错,回到步骤2检查全局变量挂载配置是否正确。
内容的提问来源于stack exchange,提问作者Paul 36
相关产品推荐
相关产品推荐

