locomotivecms/mounter — pull request #30 by jaredklewis (2014-08-31 10:47:21+00:00)
Title: Sprocket Gem Support: plug-n-play support for 16,000+ front-end assets!

## Issue
Currently, front-end assets in LocomotiveCMS are not managed. If I want to use jquery, I have to download it from the jquery site and copy it into the javascripts folder. If jquery is updated, I have to do that again. If I have a site with 5 or 6 frontend assets (let's say jquery, bootstrap, moment.js, datetimepicker, and lodash), keeping them all up to date is a huge headache.

Further, since wagon includes bootstrap and foundation in built-in generators, these generators must be constantly updated, which is cumbersome and means that the generators are usually outdated.

There has been some discussion of this topic in a Wagon issue I opened, [Wagon issue #188](https://github.com/locomotivecms/wagon/issues/188)

## The PR
This PR adds support for CSS, SASS, and JavaScript based sprocket gems. Thanks to the popular sprockets gem service, rails-assets.org, this PR effectively adds plug-n-play support for the 16,000+ front-end assets currently available on rails-assets.org. Rails-assets.org reads the bower.json files used by all major front-end asset projects to systematically package front-end assets.

So, after this PR, how does it work? If I want to add jQuery.

# Gemfile
source 'https://rails-assets.org'
gem 'rails-assets-jquery'

I can also specify the version.

gem 'rails-assets-jquery', '1.11.1'

Or

gem 'rails-assets-jquery', '2.1.1'

The above examples would lock the jquery at the specified version. It's also of course possible to use the usual operators to allow the assets to be upgraded when `bundle` is run.

gem 'rails-assets-jquery', '~> 2.1.1'

Now in any javascript file, I can include jquery using sprockets.

//= require jquery

It is also possible to include css. For example, if we want bootstrap.

# Gemfile
gem 'rails-assets-bootstrap'

And in `application.css`:

/*
=require bootstrap
*/

And it also works with sass.

// application.scss
@import "bootstrap";

The above sass import is just importing normal css, as the bootstrap gem only provides less and css. But twitter has another version of bootstrap that is written in SCSS. So if we use that, we can import the SCSS version and will be able to use the `@extend` directive to extend selectors, which is cool!

# Gemfile
gem 'rails-assets-bootstrap-sass-official'

// application.scss
@import "bootstrap-sass-official";

By default, these rails-assets.org gems include all files specified in the bower.json dist property, but it is also possible to include only the desired files.

So, for example, this would include all of Boostrap's javascript.

//= require bootstrap-sass-official

But this would only include the specified modules:

//= require bootstrap-sass-official/affix
//= require bootstrap-sass-official/alert
//= require bootstrap-sass-official/button
//= require bootstrap-sass-official/carousel

The same can be done with SASS and CSS.

## Short Comings
This PR only adds these abilities for CSS, SASS, and JavaScript. Notable shortcomings are outline below.

### LESS
Less imports are not supported, though you can still use sprocket imports in less files. Since LESS in the mounter is handled through tilt, I imagine we need to pass in the gem vendor/assets paths into tilt so that less knows where to look for imports.

### Fonts
Font assets, such as font-awesome, won't work. The css/sass files will of course import fine, but we would need to have their fonts copied from the gempath into the fonts directory for it to work currently.

I think the best solution is probably to add middleware to wagon that if a font can't be found in the public/fonts folder, it then looks for the font in the vendor/assets/fonts path of included gems.

### Images
Some front-end assets include images, such as a lightbox plugin that includes images for the close, next, and previous buttons. The problem here is identical to that of fonts, and I think it can be solved similarly.

## Conclusion
I think this PR has a lot of value as it adds plug-n-play support for many javascript and CSS based assets.

I would like to work out the remaining issues (images, fonts, and less), but was hoping to get some pointers on implementing it. Mounter is a big codebase, so I would appreciate any input or thoughts on implementing these features. Also, if the gem asset paths are going to shared by sprockets, tilt, and font/image middlewares, it might make sense to extract them from the sprockets class, but I'm not sure where a good place for that might be.

Please let me know your thoughts whenever you get a chance, Did. Thanks!