Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to manage Javascript dependencies with Bower in Rails apps?

The Javascript dependencies are growing in my Rails app and it's leading to some problems. For one, with so many it becomes difficult to track and update versions of different Javascript libraries. At first I tried turning them into gems, but then I have to manage those. Some are already gems (like backbone-rails) but I would like to have one consistent package manager.

So I'm looking into Bower, "a package manager for the web". Some blog posts from kaeff and from af83 have been helpful, but I still run into problems. I hope this question can lead to a variety of answers people can use to find the best solution for their projects.

I'd particularly like to see advice for managing assets through Bower in a Heroku deploy.

like image 638
Turadg Avatar asked Apr 28 '13 18:04

Turadg


People also ask

What is Bower dependency?

Bower provides hooks to facilitate using packages in your tools and workflows. Bower is optimized for the front-end. If multiple packages depend on a package - jQuery for example - Bower will download jQuery just once. This is known as a flat dependency graph and it helps reduce page load.

Is Bower deprecated?

Bower has been deprecated by its creators After a long and heated debate on Github, the creators of Bower decided it does not add value to the current web development stack and should be discontinued.

How do I update Bower dependencies?

Installing dependencies with one command First, you'll want to delete the bower_components folder. Bower will then look through your bower. json and download all dependencies for you. After it's done, you'll be able to find your dependencies back in the bower_components folder.

What is Bower JSON used for?

The bower. json file is actually used to define a Bower package, so in effect you're creating your own package that contains all of the dependencies for your application.


2 Answers

One way is using a version of Sprockets which allows your application.js to require packages defined by Bower. This feature was added in Sprockets 2.6, which Rails 3.x won't allow you to bundle due to a version restriction. To get that feature, you can bundle gem "sprockets", "2.2.2.backport1".

That will make Sprockets start looking for assets in vendor/assets/components too. The path is vendor/components because Bower packages could contain CSS or image assets too, not just Javascript. The way Sprockets knows what Javascript to include when you require the package is by reading the bower.json file for the main property, which says which files the pipeline should include. A gotcha here is that many Bower packages don't supply this property or supply main sources that assume RequireJS is available (e.g. d3). You can see what source main are defined with bower list --map.

When the main doesn't suit you, you can simply use Bower to manage a single remote JS file instead of a package. Josh Peek has a gist that demonstrates this. The latest version of Bower expects bower.json instead of component.json so I've updated the steps:

$ npm install -g bower $ mkdir -p vendor/assets $ cd vendor/assets/ $ curl https://raw.github.com/gist/3667224/component.json > bower.json $ bower install 

That particular bower.json loads jQuery. Then in your application.js you can simply //= require jquery and Sprockets will find it in your vendor/assets/components. To add new dependencies, just include them in your bower.json and run bower install again, for example:

{   "dependencies": {     "jquery": "http://code.jquery.com/jquery-1.8.1.js",     "d3": "http://cdnjs.cloudflare.com/ajax/libs/d3/3.0.8/d3.js"   } } 

If you want to manage your lib and vendor assets in one configuration file, you could use bower-rails, but there's not much point in using lib. That gem also provides some Rake tasks, but they don't do anything more than the basic Bower commands.

To my knowledge, there is no way yet to have Bower install as necessary during asset compilation. So if you're using a deploy environment like Heroku, you'll need to commit your vendor/assets/components directory and update it through the bower command.

It would be nice if could you require your whole Bower dependency set with one directive in application.js. A gist from kaeff illustrates how to create a require_bower_dependencies directive. There's no gem that does this for you yet. Until then, you have to declare each dependency in both bower.json and application.js.

like image 188
2 revs Avatar answered Sep 27 '22 23:09

2 revs


Checkout Rails Assets project. Usage example:

source 'http://rubygems.org' source 'https://rails-assets.org'  # gem 'rails-assets-BOWER_PACKAGE_NAME' gem 'rails-assets-jquery', '~> 1.10.2' gem 'rails-assets-sly', '~> 1.1.0' gem 'rails-assets-raphael', '~> 2.1.0' 

UPD (26.01.2016)
Future of Rails-Assets project is on discussion. Please check the thread and make your own decision: use it or find a workaround.

like image 41
a.s.panchenko Avatar answered Sep 28 '22 01:09

a.s.panchenko