Develop Your Own Gem and Gemify Your Own Assets Using Rails Engine

Develop Your Own Gem and Gemify Your Own Assets Using Rails Engine

The Rails asset pipeline, powered by sprockets, compiles (sass, coffeescript, others), aggregates (combines multiple source files into one file for performance purposes), and post-processes (minimization, gzip’ing) your assets. And which make it easy to include versioned external assets as application dependencies as well.

External assets are made available in Rails via Rails engines. When the engine is loaded into your Rails application, the engine’s asset paths are added to your application’s load paths. This makes them available for require in your manifest files. An asset gem is just an absurdly simple engine.

You will find almost any JS or CSS library you want, already Gemified, but, if it is not the case, you can Gemify those libraries by your own, and I can help you with it. So, let’s do it!

Create a bare-bones Gem:
Bundler makes it simple to create the files and directories necessary for creating a gem. Run the following command to create and initialize a Git repository along with several template files for the gem:

1
bundle gem timeago-rails

This command will create basically the following tree:

1
2
3
4
5
6
7
8
9
10
├── Gemfile
├── lib
   ├── timeago
      └── rails
              └── version.rb
   └── rails.rb
├── LICENSE.txt
├── Rakefile
├── README.md
└── timeago-rails.gemspec

Versioning
timeago-rails is a gem packaged version of the timeago.js library. Its version should track the version of JavaScript library. Open /lib/timeago/rails/version.rb and set the version:

version.rb
1
2
3
4
5
module Timeago
  module Rails
    VERSION = "1.4.1"
  end
end

Turn the Gem into an Engine
Bundler created the gem as a standard Ruby module, but we want it to be a Rails Engine.

rails.rb
1
2
3
4
5
6
7
8
require "timeago/rails/version"

module Timeago
  module Rails
    class Engine < ::Rails::Engine
    end
  end
end

Well, the module is empty. All we’re doing here is declaring the gem as a Rails Engine. This will cause Rails to add its directories to the load path when the Gem is required.

Add the Assets (Javascript library, CSS, Image) in the Gem
We’re going to create the directory /vendor/images/, /vendor/javascripts/, vendor/stylesheets/ and place the source for the timeago.js plugin there:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
├── Gemfile
├── lib
   ├── timeago
      └── rails
              └── version.rb
   └── rails.rb
├── LICENSE.txt
├── Rakefile
├── README.md
├── timeago-rails.gemspec
└── vendor
         └── assets
                  ├── images
                  ├── javascripts
                               └── timeago.js
                  └── stylesheets

Test
Moving to a sample Rails application, we can include the gem in our host application by adding it to the Gemfile using the path option:

Gemfile
1
gem "timeago-rails", path: "../timeago-rails"

Since we included an asset that needs to be included in the Rails assets, we have to take one more step and instruct the user to add the following to their app/assets/javascripts/application.js file:

application.js
1
//= require timeago-rails

This directive actually refers to the app/assets/javascripts/timeago.js file we included in our gem.

Type command below to make sure timeago.js is included in sample Rails application:

1
curl http://localhost:3000/assets/timeago.js

The curl command should return the contents of the timeago.js file if everything is correctly.

README.md
Make a simple readme file with the Gem as documentation.

Push to GitHub & RubyGems
Create a GitHub repository for the Gem, stage all of your commits, commit, and push the code to GitHub.

If you’ve never published a gem on RubyGems before, you’ll need to sign up for an account there. Your account settings will contain an API key that should be copied to ~/.gem/credentials.

Publishing your gem is as simple as:

1
rake release

So far so good, hope you enjoyed the article. see ya! :)