public
Last active

rake task for precompiling assets using sprockets within a sinatra app + view helpers

  • Download Gist
Rakefile
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
require 'rubygems'
require 'bundler'
 
Bundler.require
require './application'
 
namespace :assets do
desc 'compile assets'
task :compile => [:compile_js, :compile_css] do
end
 
desc 'compile javascript assets'
task :compile_js do
sprockets = Application.settings.sprockets
asset = sprockets['application.js']
outpath = File.join(Application.settings.assets_path, 'js')
outfile = Pathname.new(outpath).join('application.min.js') # may want to use the digest in the future?
 
FileUtils.mkdir_p outfile.dirname
 
asset.write_to(outfile)
asset.write_to("#{outfile}.gz")
puts "successfully compiled js assets"
end
 
desc 'compile css assets'
task :compile_css do
sprockets = Application.settings.sprockets
asset = sprockets['application.css']
outpath = File.join(Application.settings.assets_path, 'css')
outfile = Pathname.new(outpath).join('application.min.css') # may want to use the digest in the future?
 
FileUtils.mkdir_p outfile.dirname
 
asset.write_to(outfile)
asset.write_to("#{outfile}.gz")
puts "successfully compiled css assets"
end
# todo: add :clean_all, :clean_css, :clean_js tasks, invoke before writing new file(s)
end
application.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
require 'sinatra/base'
require 'sinatra/flash'
require 'rack/csrf'
require 'haml'
require 'sass'
require 'compass'
 
class Application < Sinatra::Application
register Sinatra::Flash
 
set :root, File.dirname(__FILE__)
set :sprockets, (Sprockets::Environment.new(root) { |env| env.logger = Logger.new(STDOUT) })
set :assets_prefix, 'compiled'
set :assets_path, File.join(root, 'public', assets_prefix)
set :compass_gem_root, Gem.loaded_specs['compass'].full_gem_path
 
configure do
sprockets.append_path File.join(root, 'assets', 'stylesheets')
sprockets.append_path File.join(compass_gem_root, 'frameworks', 'compass', 'stylesheets')
sprockets.append_path File.join(compass_gem_root, 'frameworks', 'blueprint', 'stylesheets')
sprockets.append_path File.join('assets', 'javascripts')
# ... more config
end
 
# we are deploying to heroku, which does not have a JVM, which YUI needs, so let's
# only require and config the compressors / minifiers for dev env
configure :development do
require 'yui/compressor'
require 'uglifier'
sprockets.css_compressor = YUI::CssCompressor.new
sprockets.js_compressor = Uglifier.new(mangle: true)
end
 
# ... more setup
end
asset_helpers.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
require 'sinatra/base'
 
module Sinatra
module AssetHelpers
# +options+ can pass "force_production" to trump env setting
# if digest is used in the future, will need to incorporate this into these two helpers
def stylesheets_tag(options = {})
if production? || options[:force_production]
'<link rel="stylesheet" href="/compiled/css/application.min.css" type="text/css" media="all" />'
else
'<link rel="stylesheet" href="/assets/application.css" type="text/css" media="all" />'
end
end
 
def javascripts_tag(options = {})
if production? || options[:force_production]
'<script src="/compiled/js/application.min.js" type="text/javascript"></script>'
else
'<script src="/assets/application.js" type="text/javascript"></script>'
end
end
 
helpers AssetHelpers
end
end

Great! Thank you!

All perfect but there's one thing: how about the images referenced in a stylesheet? Since you may put a style a.css in dir /assets/css, but the all-in-one stylesheet may be put as /assets/app.min.css, in the latter case image urls in app.min.css probably point to a wrong place. And the only solution seems to rewrite all urls in stylesheets before they are combined as one single. Am I right? But that sounds like a terrible work if all by automation!

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.