I've updated fetching gems from a specific bundler group. The previous version added
vendor/assets path from all gems present in the
Recently I've been thinking about different ways to seperate the view layer from Rails. With the recent hype for yeoman and grunt I've decided to give it a try. Trying to configure my default frontend stack (slim, bootstrap, coffee) made my head hurt very quickly. With my mind confused, I've began searching for a different alternative, preferably something based on Ruby.
So I've created a new Rails project and began stripping it from
ActionController, etc. so only
ActionView was left. Then I started to remove directories, gems and it occurred to me - 'What the hell am I doing?'. Instead of ripping Rails apart, I can start a clean Rack app and build from there.
So I mashed up a basic
config.ru file (based on Heroku's tutorial).
Sinatra and Asset Pipeline
Next I wanted to have something similar to the Asset Pipeline in Rails. I scratched my head for about two hours, and decided, that I don't have time to figure out, how to do this in
Rack (I'm lazy by nature), so I've searched for a bootstrapped solution. Naturally, I picked
sinatra. I've created a basic app with Bundler:
├── Gemfile ├── Gemfile.lock ├── app.rb ├── config.ru └── views └── index.slim
I've added my preferred frontend gems, alongside some utility gems, to the Gemfile:
source 'https://rubygems.org' gem 'sinatra' gem 'slim' gem 'sass' gem 'puma' gem 'coffee-script' gem 'pry'
And I created a basic
require 'rubygems' require 'bundler' Bundler.require run App
In order to get some sort of asset pipeline, I searched for a way to integrate
sinatra. The result of that search was the
Following the instructions in the
README file, I've set up a basic layout, with a Sass and CoffeScript manifest file:
In the view I've used the provided helpers, to include the assets:
I'm making heavy use of RailsAssets in my projects, and naturally I tried to use it inside my new app. Unfortunately this didn't work. I've added
rails-assets-angular to my Gemfile and included in my
app.coffee file. When I started the app, and visited the website, this is what greeted me:
Sprockets::FileNotFound at / couldn't find file 'angular'. Well that sucks. I didn't expect it to work, because I knew that, RailsAssets, go figure, only works with Rails, because it wraps all the assets inside a Rails Engine. That way all the
vendor/assetsinside the gem, are available in the Rails application.
I quickly found a way to modify the asset load path inside the
set :assets_prefix, %w(assets vendor/assets)
The question was, how to include the vendor/assets path, of the individual gems?
Bundler to the rescue
I've refactored my Gemfile to include all the asset gems inside a group:
source 'https://rubygems.org' source 'https://rails-assets.org' group :core do gem 'sinatra' gem 'slim' gem 'sass' gem 'bootstrap-sass', '~> 3.1.1' gem 'sinatra-asset-pipeline' gem 'puma' gem 'coffee-script' gem 'pry' end group :assets do gem 'rails-assets-angular' end
The next hard part was: how to fetch all the gems inside the
The solution wasn't so obvious, I spent well over 2 hours browsing bundler's documentation to achieve this (If you have a better way than the one presented below, please, leave a comment).
require 'rubygems' require 'bundler' Bundler.require(:core, :assets) require 'sinatra/asset_pipeline' require './app' assets_path = %w(assets vendor/assets) + Bundler.definition.dependencies.map do |dep| [dep.to_spec.full_gem_path, 'vendor', 'assets'].join('/') if dep.groups.include? :assets end.compact App.set :assets_prefix, assets_path App.register Sinatra::AssetPipeline run App
This solution is buttugly, but it works (for the moment). With this I finally could do:
#= require angular
The bootstrap-sass gem didn't have this problem, and worked out of the box. This is beacuse bootstrap-sass adds it's
Sass#load_paths (link to source). If we comment out that line of code, it wouldn't work, just as
rails-assets-angular didn't. If you try to require the js file, it will fail just as
That's all! Stay tuned for a follow up post, with some refactoring and configuration patterns.