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

bianjp · January 18, 2017 · Last by hiveer replied at January 21, 2017 · 2203 hits

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 中也贴出了解决方案,欢迎围观。😀

Unknow user #1 January 18, 2017

👏

挖掘得挺深的,不错

You need to Sign in before reply, if you don't have an account, please Sign up first.