58

我正在 Rails 中开始一个新项目,看起来 application.js 清单文件对我引用的 javascript 做了一些有趣的事情——它是否将这些文件缓存为资产管道的一部分?

这就是发生的事情。我在 vendor/assets/javascripts 文件夹中添加了一个名为 jquery.autoresize.js 的 javascript 文件,然后在 application.js 清单中引用该文件,如下所示:

//= require jquery.autoresize.js 

然后我启动了rails服务器。但是在我的应用程序中浏览之后,我意识到我不小心添加了错误版本的 jquery.autoresize.js 文件。因此,我删除了该文件,然后将正确的版本添加到 vendor/assets/javascripts 文件夹中。但是,令我恐惧的是,当我重新加载页面时,它仍在加载旧的 javascript 文件。

我尝试清空浏览器缓存,然后退出并重新启动 Rails 服务器,但无济于事。我通过简单地重命名我的 javascript 文件并引用新名称来共同破解一个解决方案,效果很好。但必须有一个更好的解决方案。

新的资产管道是否会以某种方式缓存您引用的文件?如果是这样,我该如何清除该缓存?谢谢你的帮助!

4

5 回答 5

63

我假设我们正在谈论生产环境。

当您在生产环境中更改任何 javascript 或样式表时,您需要运行rake assets:precompile;此任务编译和压缩各种 .js 和 .css 文件,并创建您的视图加载的 application.js 和 application.css 文件。

如果您替换jquery.autoresize.js为具有较旧时间戳的版本,则预编译步骤可能会跳过它,认为编译的版本是最新的。您可以通过首先运行来避免这种情况,强制它从头开始rake assets:clean重建目录中的所有内容。public/assets

于 2012-09-05T23:22:52.497 回答
50

也试试rake assets:clobber。这将完全重置所有内容并删除所有已编译的资产。另外,我经常需要在推送到生产之前设置环境:RAILS_ENV=production rake assets:precompile.

于 2015-07-20T13:11:13.053 回答
27

每次编辑内容时,Rails 都会自动清除单个文件的缓存。要清除单个文件的缓存,只需打开文件,编辑一行代码,然后重新保存即可。Rails 将清除该文件的缓存,并且浏览器将在下次加载页面时加载新文件。

jquery.autoresize.js 使用文件的旧缓存版本的原因是因为旧版本被删除,然后新版本被复制并以相同的名称粘贴到同一文件夹中。因为文件本身从未被编辑过,Rails 继续使用缓存的旧文件。

这是因为资产管道对缓存使用指纹。

指纹识别是一种使文件名依赖于文件内容的技术。当文件内容改变时,文件名也随之改变。对于静态或不经常更改的内容,这提供了一种简单的方法来判断文件的两个版本是否相同,即使跨不同的服务器或部署日期也是如此。

当文件名是唯一的并且基于其内容时,可以设置 HTTP 标头以鼓励各处的缓存(无论是在 CDN、ISP、网络设备还是 Web 浏览器中)以保留自己的内容副本。当内容更新时,指纹会发生变化。这将导致远程客户端请求内容的新副本。这通常称为缓存清除。

Rails 用于指纹识别的技术是在名称中插入内容的散列,通常在末尾。例如,可以使用其内容的 MD5 摘要重命名 CSS 文件 global.css:

global-908e25f4bf641868d8683022a5b62f54.css

因此,如果您删除清单中引用的文件,然后复制到具有相同名称的新文件中,则永远不会发生缓存破坏。当您编辑文件时,指纹会启动,并为文件名生成一个新的哈希值。这会破坏该文件的缓存。

有关完整的故事,请参阅什么是指纹识别以及我为什么要关心?.

于 2012-04-04T04:23:28.267 回答
19

rake tmp:clear为我做了诀窍,我正在使用更少的导轨。

于 2016-08-10T17:21:09.960 回答
6

我用config.assets.version = '1.01019'application.rb的来破坏整个缓存。当我想推送一个完整的新版本时,我会增加版本,这样就可以了。这会处理那些 Rails 出于任何原因没有重新编译为资产的边缘情况。

于 2015-03-03T21:15:52.660 回答