Rails Rails 预编译后请求 CSS, JS 文件的 URL 未更新

dgy1126 · 2014年10月10日 · 最后由 dgy1126 回复于 2014年10月11日 · 3116 次阅读

下午将 rails 项目的 stocks.js 文件修改后,使用 cap qa deploy 命令对项目进行部署,但是发现部署之后,浏览器请求的 stocks.js 文件的文件名是部署之前的,即 stocks-59c6ede76fa709dc52fa25971a054f4b.js。

而此时 cap 命令中使用的 bundle exec rake assets:precompile 命令将 stocks.js 文件预编译,并在 public 目录下将文件名改为了 stocks-21133....ff8,js,导致浏览器无法得到 stocks.js 文件,返回 404 错误。

查看 manifest.json 文件,发现 stocks.js 对应的是更新之后的 stocks-21133....ff8,js。

我想请教大家的就是,为什么预编译之后 rails 将文件名更新了,但是请求文件的 url 没有更新呢?

谢谢大家!

这是部署完成之后访问网页的情况,网页请求的是 stocks-59c6ede76fa709dc52fa25971a054f4b.js:

但是此时服务器上的 public 目录里已经没有 stocks-59c6ede76fa709dc52fa25971a054f4b.js,因为预编译之后将文件名改成 stocks-21133....ff8,js 了。

你是在 production 环境启动的 Rails 么?

#1 楼 @huacnlee 不是啊,是测试环境,用的是 Unicorn

#2 楼 @dgy1126 … 我不知道你指的是什么,请说清楚一些

#3 楼 @huacnlee 我在原帖里把问题重新描述了一遍,请查看

你知道什么是 Rails.env 或 RAILS_ENV 么?你跑的是什么?

  • 如果你确定 Rails.env 是 production,那么请检查你的 config/environments/production.rb,确定里面的assets.digest 得是 true config.assets.digest = true,请阅读:《Rails Guides - Assets Pipeline - 生产环境
  • 如果你的 Rails.env 不是 production,那么你需要学习 Rails,以及 Rails 部署相关的文档
  • 如果你不知道 Rails.env 是什么,不清楚怎么看,那么你还需要把 Rails Guides 完整阅读一遍。

下面这些文档有看过看完么:

#5 楼 @huacnlee

  1. 我确定 Rails.env 是 qa,我部署的是测试环境,config/environment/qa.rb 中 config.assets.digest = true,预编译的命令为 RAILS_ENV=qa bundle exec rake assets:precompile。
  2. Rails.env 确定不是 production,请问 production 环境的 Rails 部署和其他环境部署有什么区别吗?

config/environment/qa.rb的截图如下:

我再次看了一下你主贴给的截图,Rails HTML 生成的时候以及有 Assets 的 digest 的,只是和你预编译出来的文件不一样,所以和环境配置文件没有关系。

  1. 发布以后 stocks-59c6ede76fa709dc52fa25971a054f4b.js 没有了?

    原因:Capstrano 新发布以后,会在 releases 目录创建一个当前时间的新目录,current 目录是软连接过去的,所以你之前预编译出来的文件在 current/public 下面就没有了

  2. Rails HTML 结果里面依然还是调用的 stocks-59c6ede76fa709dc52fa25971a054f4b.js 原因:你是不是预编译以后,没有重启过 Unicorn?

#7 楼 @huacnlee 刚刚检查了一下,确实是 unicorn 没有重启导致的,谢谢您!

#7 楼 @huacnlee 另外多问您一句,为什么 unicorn 不重启会导致 html 中调用 js 的 url 不变呢?

#9 楼 @dgy1126 因为 Rails 对这些计算的东西有缓存的(内存缓存),这个动作是在启动后第一次请求的时候做的,以后得请求都是用缓存的值,以减少重复运算。

#10 楼 @huacnlee 我可以理解为 unicorn 会缓存 manifest.json 文件吗?因为原文件名到带 MD5 值的编译后的文件名的映射是保存在 mainifest.json 文件里的。

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