Many Rails gems these days bundle third-party assets, JavaScript assets in
particular.

Oftentimes gem authors simply dump .js files into their repository, sometimes
even concatenated build products. It’s a simple solution, and with tools like
Vendorer it doesn’t have to turn into a
maintenance headache.

But this makes it hard for users of your gem to contribute to your asset
upstream (that is, to the third-party code that you include). Imagine I am a
user of your gem: If I want to fix a bug in your gem code, it’s easy: I can
clone your repository, point the gem in my Gemfile at my checkout or fork
(with :path or :git), hack away at your code, and send you pull requests,
while all my changes are instantly live in my app. But I cannot do the same to
fix a bug in the third-party code you are shipping, since the version you
ship is almost never up-to-date with the upstream master. And if I cloned the
upstream, I would have trouble getting my fix back into your gem so I can use
it in my app immediately. By losing that instant gratification, I’m much less
likely to contribute to the upstream.

Luckily, this is easy to fix: Include the upstream using a Git submodule.
Then add a Rake task that copies or builds the files into vendor/assets.

Now it’s easy to contribute: I simply clone your repository and set :path as
before, and then check out the master branch on the submodule. I can hack away
and send pull requests to the upstream straight from the submodule, while at
the same time my changes to the upstream will be live in my app through your
gem.

I call this quality contributor-friendliness. It’s not so much a service to
your users – most won’t even care – as it is to the upstream project. By
making it easy to contribute through your gem, you have expanded the upstream’s
base of potential contributors with your users.

I think making open source work better is worth the overhead of using
submodules, even if dumping vendor files might be easier sometimes. Our
upstream maintainers provide all this awesome code. Let’s be nice to them and
make our gems contributor-friendly.


Update June 2012:

This has been used in practice in
Konacha and
jquery-ui-rails. It seems to be
working well so far.

To see a working Rake task, check the :assets task in Konacha’s
Rakefile
.

One insight we’ve had is to always check in the generated asset files. This is
necessary so your library can be used in Bundler like so:

1
gem 'foo', :git => '...'

Bundler obviously won’t run your build step, so everything needs to be checked
in.

Read more at the source