Heroku生产环境下application.js无法加载及路由错误求助
看起来你遇到的是Heroku部署里常见的Asset Pipeline与UJS相关坑,我之前也踩过类似的,咱们一步步来捋:
一、先搞定静态资源404问题(这也是DELETE链接失效的根源)
1. 检查production.rb的核心配置
打开config/environments/production.rb,确保这几项配置正确:
# 开启静态文件服务(Heroku必须依赖这个) config.public_file_server.enabled = true # 启用资源指纹,避免浏览器缓存旧资源 config.assets.digest = true # 临时排查可以打开这个(但长期建议关闭,影响性能) # config.assets.compile = true
注意:config.assets.compile = true会让Rails在运行时动态编译资源,仅作为临时排查手段,最终要关闭,确保所有资源都提前预编译完成。
2. 确保预编译列表包含所有需要的文件
打开config/initializers/assets.rb,把你单独引用的JS/CSS加到预编译列表里:
# 如果你的jQuery是单独文件而非通过gem引入,一定要加这个 Rails.application.config.assets.precompile += %w( jquery-1.8.3.min.js )
要是用jquery-railsgem的话,就不用单独加,gem会自动处理依赖。
3. 本地预编译后再推送到Heroku
Heroku的自动预编译偶尔会抽风,建议本地预编译完再提交:
- 先删掉本地旧的预编译资源:
rm -rf public/assets - 本地执行生产环境预编译:
RAILS_ENV=production rake assets:precompile - 把预编译后的资源加入git:
git add public/assets - 提交并推送:
git commit -m "Precompile assets for production" && git push heroku main
4. 检查Gemfile和application.js的依赖
- Gemfile:确保asset和jQuery相关的gem不在development组里:
gem 'jquery-rails' gem 'sass-rails', '>= 5.0' gem 'uglifier', '>= 1.3.0' gem 'coffee-rails', '~> 5.0.0'
执行bundle install后再做预编译。
- application.js:正确引入UJS和jQuery,确保依赖链完整:
//= require jquery //= require jquery_ujs //= require rails-ujs //= require_tree .
这样所有依赖会被合并到application.js里,避免单独引用的路径混乱。
5. 修复application.html.erb的资源引用
别用相对路径写JS引用!比如<script src="js/jquery-1.8.3.min.js"></script>会导致在/users页面下请求/users/js/...,直接404。改用Rails的asset helper:
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
这样不管当前页面路由是什么,都会生成正确的/assets/application-xxxx.js路径。
二、解决link_to method:delete失效的问题
这个问题90%是因为UJS没加载成功,导致点击链接时发的是GET请求而非DELETE请求,触发路由错误。搞定上面的资源问题后,这个通常会自动修复,不过可以再做这些检查:
- 确认application.html.erb里已经包含
javascript_include_tag 'application'(前面已经提到),UJS完全依赖这个文件。 - 检查link_to的写法是否标准:
<%= link_to '删除用户', user_path(user), method: :delete, data: { confirm: '确定要删除吗?' } %>
注意:method: :delete和data: { confirm: ... }都需要UJS支持,没加载UJS的话这些属性就是摆设。
3. 打开浏览器控制台(F12),看看有没有JS报错,比如找不到$或jQuery,这说明jQuery没加载成功,回到第一步排查资源问题。
最后验证
部署完后,用浏览器开发者工具确认:
- Network标签里,所有JS文件都是200状态码,路径是
/assets/...而非/users/assets/... - 点击DELETE链接时,请求方法是DELETE而不是GET
如果还有问题,拉取详细Heroku日志看看:heroku logs --tail,排查有没有其他隐藏错误。
内容的提问来源于stack exchange,提问作者nourza

