Rails asset pipeline and digest values

Go To StackoverFlow.com

6

Does anyone know how exactly the asset digest value is calculated? If I have two JS files which contain various other included JS scripts then will each file maintain the same digest hash if none of the inner scripts have been changed? Or is a new digest value calculated each time the assets:precompile operation is run?

2012-04-05 02:10
by matsko


1

Grabbed from rails guides

When a filename is unique and based on its content, HTTP headers can be set to encourage caches everywhere (whether at CDNs, at ISPs, in networking equipment, or in web browsers) to keep their own copy of the content. When the content is updated, the fingerprint will change. This will cause the remote clients to request a new copy of the content. This is generally known as cache busting.

The technique that Rails uses for fingerprinting is to insert a hash of the content into the name, usually at the end. For example a CSS file global.css could be renamed with an MD5 digest of its contents

2012-04-05 02:18
by Tomato
So is a simple md5_file() operation performed on the final file after all the merging and compression is performed? That md5 value ends up being the digest for the file correct - matsko 2012-04-05 02:33
According to the docs, yes. You can refer to another guide for more details - Tomato 2012-04-05 03:13


42

The accepted answer is not quite true. We build static assets for our staging, demo and production servers, and the same asset is given different digest values in each case.

It turns out that the Rails environment is also being taken into consideration. Sprockets creates the digest as follows:

# Sprockets::Environment::initialize
@digest_class = ::Digest::MD5

# Sprockets::Base::digest
@digest ||= digest_class.new.update(VERSION).update(version.to_s)

# Sprockets::Base::file_digest(path)
digest.file(path.to_s)

# Sprockets::Asset::initialize
@digest = environment.file_digest(pathname).hexdigest

Rails hooks into Sprockets as follows:

# Sprockets::Railtie
app.assets = Sprockets::Environment.new(app.root.to_s) do |env|
  env.version = ::Rails.env + "-#{config.assets.version}"
  ...
end

So rails is creating a Sprockets environment that has a version equal to the Rails environment, and Sprockets uses the version when creating the digest class.

2012-10-22 06:23
by kranzky
This is the correct answer - Litmus 2013-11-22 07:22
Thanks for this one. I had to change the digest on my assets to invalidate Cloudflare cache without changing the assets files content. Changing the config.assets.version from "1.0" to "1.1" changes the signature ; - luigi7up 2016-01-08 12:11
What version of Rails is this true for? It would be good to have an update for Rails 5 if it has change - Peter P. 2018-12-14 19:09
Ads