Front-End Dependency Management with Bower & RoR

by Miles Matthias

Dependency management can be tricky. When I came on board at dojo4 a few weeks ago, it was awesome to clone a ruby on rails project repo, be able to do a bundle install and then be able to run the app with rails s. For those of you that aren't familiar with ruby on rails dependency management, the gems that are needed to run the application are listed in a file named Gemfile. The bundle application reads this gemfile and downloads and installs any gems that aren't on your computer yet. Not only does this make it easy for getting the application up and running correctly quickly and without much setup effort, it also makes it easy to update those dependent gems when a new version is released. Running bundle update or updating the gemfile and running bundle install again makes this an easy process that guarantees every other user of the app will be using the new version too (granted that we share the changes via source control). This is a great workflow for the server side of things, but what about the client side?

As client applications get more complicated, we frequently need the assistance of libraries and frameworks on the client too. At dojo4, we currently download the files we need and manually drop the required files into source control and commit them. The files are under source control, so at least everyone will get those files and we can revert a version upgrade, but it's sort of messy. To update the library files we have to repeat the manual process. On the server side, it's also really nice that dependency management tasks are less tightly coupled with the application code so that updating and rolling back versions are easier. Unfortunately, there hasn't been a good way to manage dependencies for the front end. Until recently.

In September of last year, Twitter released Bower, which offers "a generic, unopinionated solution to the problem of front-end package management". Bower provides the same capabilities for the front-end application that bundle does for the back end: a central listing of dependencies in one file, easy install and update commands, and some separation from app code and commits. While researching how we could take advantage of this in our standard ruby on rails application, I was referred by the Bower creators to the bower-rails gem, which integrates bower into the ruby on rails directory structure and adds some rake commands to run bower commands. Now instead of manually committing library files to the app repo, a developer can do rake bower:install [package name] and the latest version of that package will be installed in the asset pipeline and will be added to the list of required packages. A new developer can then download the app code and after running bundle install, can run rake bower:install and all of the front-end dependencies will be installed in the proper directory in the ruby on rails asset pipeline for immediate use.

Personally, I really like this approach and am hopeful that we can convert the front-end libraries that are manually added to the bower approach. We're still discussing the benefits and drawbacks internally and will make a decision soon. What do you think? How do you handle front-end dependencies in a distributed team?