My GitHub @otobrglez

Bower + Rails on Heroku and S3

21 Jan 2014 / rails

My recent project is single-page application that has front-end build with Marionette.js and back-end written in Ruby on Rails. Since I want to use top front-end packages, as easy as possible I used "new" package manager for front-end called Bower.

Enter Bower

Bower is front-end package management system, written in JavaScript and it uses Node and npm in its base. Packages are managed via Git and you can use any type of transport with it (AMD, CommonJS,...)

Visit Bower to learn more about and browse packages.

Pre-requirements

Setup

  1. Update your Gemfile with execjs and asset_sync.
  gem 'rails'
  # ... whatever u need here
  gem 'execjs'
  gem 'asset_sync'

asset_sync Gem will synchronize assets between Rails (on Heroku) and your S3. Please configure asset_sync before going on. Instructions are on Github

  1. Enable assets precompilation on Heroku
  heroku labs:enable user-env-compile -a myapp
  1. In top folder of your Rails project create file package.json.
  {
      "name": "myapp",
      "version": "0.0.1",
      "engines": {
        "node": "v0.10.x",
        "npm": "1.3.x"
      },
      "dependencies": {
        "bower": "1.2.x"
      },
      "scripts": {
        "postinstall": "bash prepare_bower.sh"
      },
      "repository": {
        "type" : "git",
        "url" : "http://github.com/me/myapp.git"
      }
  }

package.json is standard "package" format for npm. Notice the postinstall. postinstall is script that will be called after npm has installed package. In our case; after all packages from npm ware installed we want to prepare bower and its dependencies.

  1. prepare_bower.sh is simple script that will check if bower_components ware already installed. If they ware; it will remove folder. I came up with this script due to bug that coused problems on Heroku.
  #!/usr/bin/env bash

  echo "Prepare Bower"

  if [ -d vendor/assets/bower_components ]; then
      echo "Removing components"
      rm -rf vendor/assets/bower_components
  fi

  node_modules/bower/bin/bower install
  1. Create bower.json and define your dependencies
  {
      "name": "myapp",
      "dependencies": {
        "sugar": "*",
        "marionette": "*",
        "backbone.stickit": "*"
      }
  }
  1. Tell Bower where he should install all dependencies in .bowerrc
  {
      "directory": "vendor/assets/bower_components"
  }
  1. Configure Rails so that it know where to look for Bower components. Update your application.rb
    # ....
    config.assets.paths << Rails.root.join('vendor', 'assets', 'bower_components')
    # ...
  1. Use bower components in your application.js
  #= require sugar
  #= require backbone/backbone
  #= require backbone.stickit/backbone.stickit
  1. Heroku by default support only one "kind" of app. Either Ruby or Node but not both at the same time. Since, out project behaves as Ruby and Node app we need to use custom build pack to run it.

Add buildpack-multi to your Heroku instance

  heroku config:add BUILDPACK_URL=https://github.com/ddollar/heroku-buildpack-multi.git

Create new file .buildpacks and add this two lines to it

  https://github.com/heroku/heroku-buildpack-nodejs
  https://github.com/heroku/heroku-buildpack-ruby

Summary

If everything is configured correctly only thing that you should do when you want to deploy is

git push origin master

And Heroku will take care of the rest.

And on your local machine you now run this command each time you add packages to bower

npm install

Is't that nice? :)


comments powered by Disqus