Sprockets & Bower in my Padrino please.
One of the things that Padrino doesn't come out of the box with is Sprockets, a rack middleware for asset packaging & management. This decision makes sense as not every app needs something like that, or should even be forced to use it. There are other alternatives like jammit and sinatra-assetpack that you can use as well. But should you need Sprockets specifically, it's pretty easy getting it setup. First up, you'll need to include a few libraries. Add the sprockets gem and sprockets-helpers gem to your Gemfile. If you want compression as well, we can add it here, but let's put that for our development group only so we don't load it during production.
# Gemfile
# ...
gem 'sprockets'
gem 'sprockets-helpers'
group :development do
gem 'yui-compressor'
gem 'uglifier'
end
We'll create a configuration setup for our Sprockets to include all the asset directories we want to have it consume. Here we can also append our Bower components/ directory as well for Sprockets to manage. Also notice that I'm placing my assets/ folder on the root of the application. I like keeping my assets part of the entire app, so if I do include subapps, they can just as easily leverage these directories as well. That's not to say they can't invoke it from it being nested in something like app/assets/, it feels much clearer to see top level directories as something shared amongst all the applications.
# config/sprockets.rb
SPROCKETS = Sprockets::Environment.new(File.expand_path('../../', __FILE__))
SPROCKETS.append_path File.expand_path('../../assets/stylesheets', __FILE__)
SPROCKETS.append_path File.expand_path('../../assets/javascripts', __FILE__)
SPROCKETS.append_path File.expand_path('../../assets/images', __FILE__)
SPROCKETS.append_path File.expand_path('../../assets/vendor/stylesheets', __FILE__)
SPROCKETS.append_path File.expand_path('../../assets/vendor/javascripts', __FILE__)
SPROCKETS.append_path File.expand_path('../../assets/vendor/images', __FILE__)
SPROCKETS.append_path File.expand_path('../../components/', __FILE__)
if PADRINO_ENV == 'development'
SPROCKETS.css_compressor = YUI::CssCompressor.new
SPROCKETS.js_compressor = Uglifier.new(mangle: true)
end
The sprockets-helpers gem gives us some nice helpers to use to retrieve the paths of our sprocket-powered assets. We can include these helpers a few different ways but well just put it into our app.rb via the #helpers. Also, if you generated the app with a stylesheet library like sass or less, go ahead and removed the registered initializer from your application. Sprockets will be doing all that work now.
# app/app.rb
require File.expand_path('../../config/sprockets', __FILE__)
module Web
class App < Padrino::Application
register Padrino::Rendering
register Padrino::Mailer
register Padrino::Helpers
helpers Sprockets::Helpers
configure do
set :sprockets, SPROCKETS
# We can configure `sprockets-helpers` to find the correct assets for us.
Sprockets::Helpers.configure do |config|
manifest_path = Padrino.root('public/assets/manifest.json')
config.environment = sprockets
config.prefix = '/assets'
config.manifest = Sprockets::Manifest.new(sprockets, manifest_path)
config.digest = true
config.public_path = public_folder
end
end
end
end
We will want to be able to precompile are assets before we push our code to production. However, we will also need a way to also view our changes in development as well. Let's add to our config.ru:
# config.ru
#!/usr/bin/env rackup
# encoding: utf-8
# This file can be used to start Padrino,
# just execute it from the command line.
require File.expand_path("../config/boot.rb", __FILE__)
if PADRINO_ENV == 'development'
map '/assets' do
run Web::App.sprockets
end
end
run Padrino.application
Let's go ahead and add the final piece for our pre-compilation in Rakefile:
# Rakefile
PADRINO_ENV = ENV['PADRINO_ENV'] ||= ENV['RACK_ENV'] ||= 'development' unless defined?(PADRINO_ENV)
require 'bundler/setup'
require 'padrino-core/cli/rake'
require 'sprockets/../rake/sprocketstask'
Bundler.require(PADRINO_ENV)
require File.expand_path('../config/sprockets', __FILE__)
PadrinoTasks.use(:database)
PadrinoTasks.use(:sequel)
PadrinoTasks.init
Rake::SprocketsTask.new do |t|
manifest_path = File.expand_path('../public/assets/manifest.json', __FILE__)
t.environment = SPROCKETS
t.output = File.expand_path('../public/assets', __FILE__)
t.manifest = Sprockets::Manifest.new(SPROCKETS, manifest_path)
t.assets = %w(application.js application.css)
end
Alright! With all of this setup we can go ahead and create our sprocket powered assets and include them into our views with something like:
# app/views/layouts/application.slim
doctype html
html
head
# ...
link href=stylesheet_path('application') media="screen" type="text/css" rel="stylesheet"
Since we have Sprockets being loaded via config.ru, we need to use it via the file directly or something like rackup:
web $ rackup config.ru -p 3000 [2013-03-29 05:15:29] INFO WEBrick 1.3.1 [2013-03-29 05:15:29] INFO ruby 2.0.0 (2013-02-24) [x86_64-darwin12.2.0] [2013-03-29 05:15:29] INFO WEBrick::HTTPServer#start: pid=13597 port=3000
Okay, we've made it this far. When we are ready to do a push to production, we can run our Sprockets rake tasks to help doing the pre-compilation. You should see something like this:
web $ rake assets I, [2013-03-29T04:57:30.185976 #13086] INFO -- : Writing /web/public/assets/application-e08d1625e051d63293e26ce3eb4100de.css
And there we have it. We should have our assets pre-compiled and app ready to go. That wasn't so hard was it? Thanks for reading!



