Wrapping the bootstrap-sass gem in another gem causes asset manifests to break

837 views Asked by At

I'm trying to wrap the bootstrap-sass gem inside another gem (let's call it my-engine). Along the way, I'm building a small Rails application to test things out. As a first step, I wanted to make sure I could get bootstrap-sass working directly in my Rails application. The Gemfile for the Rails app looks like this:

gem 'bootstrap-sass', '3.3.1.0'
gem 'my-engine, path: "~/dev/my-engine"

This works fine. The bootstrap assets are loaded into my Rails application and everything looks good. Now, I want to take bootstrap-sass out of my Rails app and let it load through my-engine. So, my Rails application Gemfile now looks like:

gem 'my-engine, path: "~/dev/my-engine"

The .gemspec for my-engine has:

spec.add_runtime_dependency 'bootstrap-sass', '3.3.1.0'

I can re-bundle the my-engine gem with no problems. I can re-bundle the Rails application with no problems. However, when I refresh the page of the Rails app, I get the following error:

File to import not found or unreadable: bootstrap-sprockets.

That break occurs when sprockets is trying to build the application.css file. Sometimes this will pass and I'll get a different error about missing the bootstrap.js javascript file when the application.js is being built.

Why is this happening? I'm wondering if it has something to with the fact that I'm developing the gems locally and haven't published them, although I'm not sure why that would affect bootstrap-sass which is published. I'm using bundler 1.5.3.

2

There are 2 answers

0
WebDev On BEST ANSWER

Make sure 'bootstrap-sass' is required in your engine. One sensible place to do this is in your lib/my-engine.rb file:

require 'bootstrap-sass'

Adding the bootstrap-sass gem as a runtime dependency in the .gemspec isn't enough when you're trying to wrap gems.

1
kross On

As you want to use more and more scss/js/coffeescript libraries, you may want to consider moving to bower vs gemfiles as the source for bootstrap-sass-official. We use bower-rails for rake tasks and auto-configuration. It's a really lite config/rake task layer over standard bower.

Addressing your answer, bootstrap problems via the gem was one of the reasons I switched our engine over to just bower assets. We now import bootstrap-sass-official and have full control, note however that for sass files you will need to import the longer path to the source file, i.e. in our engine _application.scss:

# our custom variable overrides
@import 'overrides/variables';

@import 'bootstrap-sass-official/assets/stylesheets/bootstrap-sprockets';
@import 'bootstrap-sass-official/assets/stylesheets/bootstrap';

NOTE: if you want your app sass variables to override engine and sass variables, make sure your engine has _application.scss not application.scss, the leading underscore is critical for variable context/scope.

Thinking ahead, you may need to ignore bower transitive dependencies as we did. (i.e. some dependencies may use 'bootstrap' while others use 'bootstrap-sass-official' etc)

We use it like this in our .bowerrc such as the following:

{
  "ignoredDependencies": [
    "bootstrap",
    "bootstrap-sass",
    "bootstrap-sass-official"
  ]
}

In conclusion We have been using this for several months with success. bower-rails will install the dependencies in /vendor/assets and if referenced in your engine, you won't need to reference them at all in your application project. It has been fast and easy to maintain/add/update libraries and know exactly how files are included.