A.K.A. The Rails asset pipeline.
          
        
        
        The Last-Modified header
GET /ajax/libs/jquery/1.11.1/jquery.min.js HTTP/1.1
Host: ajax.googleapis.com
Accept: text/javascript
HTTP/1.1 200 OK
Content-Type: text/javascript; charset=UTF-8
Last-Modified: Tue, 13 May 2014 02:26:31 GMT
Date: Thu, 10 Jul 2014 08:51:40 GMT
<94 KB of JS>
GET /ajax/libs/jquery/1.11.1/jquery.min.js HTTP/1.1
Host: ajax.googleapis.com
Accept: text/javascript
If-Modified-Since: Tue, 13 May 2014 02:26:31 GMT
HTTP/1.1 304 Not Modified
<JS is not sent again>
        
          
          But can do better.
The Expires / Cache-Control headers
GET /ajax/libs/jquery/1.11.1/jquery.min.js HTTP/1.1
Host: ajax.googleapis.com
Accept: text/javascript
HTTP/1.1 200 OK
Content-Type: text/javascript; charset=UTF-8
Cache-Control: max-age=31536000, public
Date: Thu, 10 Jul 2014 08:51:40 GMT
<94 KB of JS>
        No other request will be issued for a year
          
        But how can I update my assets then?
        Append the file mtime as query string
<script src="/javascripts/application.js?1405197924" ...
          Include the file MD5 in the file name
<script src="/assets/application-d3b07384d113edec49eaa6238ad5ff00.js"
          //= require jquery
//= require_tree myapp
//= require_self
//= depend_on config
//= stub prototype
          depend_on do not include the file, but use it to compute the MD5 sumstub can be useful to prevent one of your dependency from requiring somethinginclude (deprecated) like require without the unicity# config.js.coffee.erb
@Config = 
  truth: <%= 21 * 2 %>
          class Csv2Json < Tilt::Template
  def evaluate(scope, locals, &block)
    JSON.dump(CSV.parse(data))
  end
end
Sprockets.register_engine '.csv', Csv2Json
# foo.json.csv
Id,Name
1,George Abitbol
// foo-6d04991772b0ab12f0a96971ad290d68.json
[["Id","Name"],["1","George Abitbol"]]
          Processors are Tilt templates like engines, but they do not convert the asset to another type
Sprockets.register_preprocessor 'text/javascript', RemoveBreakPoints
Sprockets.register_postprocessor 'text/javascript', PrependSafetySemiColon
Sprockets.register_bundle_processor 'text/javascript', MinifyJS
          Note that processors are registered by MIME type while engines are registered by extensions.
Shorthand methods
environment.js_compressor  = :uglify
environment.css_compressor = :scss
        The sprockets context provide helpers to engines, which can eventually expose them to the transormed assets
/* main.css.erb */
.header { background-image: url(<%= image_path('header-background.png') %>);}
          They are mostly available in .erb assets.
// main.css.scss
.header { background-image: image-url(header-background.png); }
        But some engines like SCSS provide integrated support
Most usefull ones are:
image_path, font_path, etc. Gives you the digested path of another asset.asset_data_uri gives you the Base64 encoded asset content (for embeding images).And you can of course add custom ones
Even if he is often nicknamed "The Rails asset pipeline", Sprockets is actually framework agnostic
It can even easilly be used in non Ruby projects (PHP, Node, Python, etc)
# lib/sprockets_environment.rb
require 'sprockets'
module MyEnvironment < Sprockets::Environment
  def initialize(production=true)
    root = File.expand_path(File.join(__dir__, '..'))
    super(root + '/public')
    append_path(root + '/app/assets/javascripts')
    append_path(root + '/app/assets/stylesheets')
    append_path(root + '/app/assets/images')
    if production
      self.css_compressor = :scss
      self.css_compressor = :uglifier
    end
  end
end
        All the configuration would happen in a subclass of Sprockets::Environment
# config.ru
require 'sprockets_environment'
map '/assets' do
  run MyEnvironment.new
end
        Sprockets::Environment acts as a rack middleware.# Rakefile
require 'rake/sprocketstask'
require 'sprockets_environment'
Rake::SprocketsTask.new do |t|
  t.environment = run MyEnvironment.new
  t.output      = "./public/assets"
  t.assets      = %w( application.js application.css )
end
        rake assets:precompile will statically compile every listed bundles.manifest.json file will be generated, containing all the mapping between the source files and the compiled files.# in your app helpers
ASSETS_ROOT = 'https://my.cdn.com/assets/'
def sprockets
  @sprockets ||= begin
    env = MyEnvironment.new
    ENV['RACK_ENV'] == 'production' ? env.index : env
  end
end
def script_url(name)
  ASSETS_ROOT + sprockets.find_asset(name + '.js').digested_path
end
script_url('application') # => 'https://my.cdn.com/assets/application-d3b07384d113edec49eaa6238ad5ff00.js'
        assets directory between releases.public/ directory or fix the few URLs.Jean Boussier
Shopify
https://github.com/byroot