Rails Rails 5 + guard-livereload 不能热更新 CSS 的解决方案

bianjp · 2017年01月18日 · 最后由 hiveer 回复于 2017年01月21日 · 2205 次阅读

guard-livereload 是个非常棒的工具,做前端开发时会非常方便:修改 view, Javascript 后自动刷新页面,修改 CSS 后热更新 CSS 而不刷新整个页面。

但最近在 Rails 5.0.1 下使用时却不能热更新 CSS 了。加载新 CSS 文件的请求,Rails 竟返回 404:

搜索了一下,有人已给 guard-livereload 提了个 issue,但并没有人提出解决方案,只好自己动手排查了。

过程就不细说了,主要是深入 Rails/Sprockets 的源代码找到处理 assets 请求的代码,粗暴地在 gem 安装目录( ~/.gem/)下直接修改 sprockets 的代码,输出一些变量的状态以辅助理解代码。

原因

多个原因共同导致 asset 请求返回 404:

  1. livereload 在热更新 CSS 时,只在原 URL 的查询字符串中加了个时间戳,并没有更新 URL 中的 digest
  2. Sprockets 会验证 URL 中的 digest 与实际的 digest 是否一致,不一致就返回 404
  3. Rails 4.2 生产的 asset URL 中包含 "?body=1",Spockets 为了兼容 2.x 版本,看到 "?body=1" 就会跳过 digest 验证
  4. 但 Rails 5 生成的 asset URL 中不包含 "?body=1" 了。同时 Sprockets 4.0.0 beta 也删掉了兼容 2.x 版本的代码,不能再通过 "?body=1" 禁止 digest 验证了。

解决方案

config/environments/development.rb 中加入或修改

config.assets.digest = false

以禁止在 URL 中包含 digest,从而绕过 Sprockets 的 digest 验证。

我在原 issue 中也贴出了解决方案,欢迎围观。😀

挖掘得挺深的,不错

需要 登录 后方可回复, 如果你还没有账号请 注册新账号