简体   繁体   中英

rails engines and assets

I have a rails engine that has a widget in it. I'm rendering the widget using a layout: false property in render and to style the widget, I'm recycling CSS on my main app.

Now here's the tricky part, I only needed 3 stylesheets for my widget and 2 of them are in my main app, those are bootstrap.css and _ss_font.css. On development, it works fine but when I push it to production, I'm having an error on bootstrap.css, it seems that it's dependent on another file on my vendor assets. How do I include those assets?

Note: If I use =stylesheet_link_tag "application" my problem is partially resolved but I have to handle conflicting class names and it will include all assets on my application. I just want to load the necessary stylesheets to style my widget in the engine.

EDIT 1

As suggested I'm including a more descriptive explanation on this:

So this is the error I'm having.

ActionView::Template::Error (File to import not found or unreadable: ss-variables. Load path: /data/serviceseeking_au_staging/releases/20140604114806 (in /data/serviceseeking_au_staging/releases/20140604114806/vendor/assets/stylesheets/bootstrap.scss)):

 2: !!! 5 3: %html 4: %head 5: = stylesheet_link_tag "bootstrap", "_ss_font", "feedback/reviews-widget" 6: 7: %body 8: .reviews-container lib/action_logger.rb:31:in `call' 

This view is inside the engine. As you can see, this is my ideal goal, to only include 3 stylesheets. There's not much to see on the reviews-widget , it's just sass without any external file dependency so I will not show it. So looking at the error message, where is this "ss-variable"? Well, let me take you guys on a field trip first before we arrive there.

I first traced where bootstrap.scss is and found it sitting on the main app under the vendor/assets/stylesheets folder. It's contents are as follows:

 @import "bootstrap/variables";
 @import "bootstrap/mixins";

 @import "bootstrap/scaffolding";

 @import "bootstrap/grid"; 
 @import "bootstrap/layouts";

 etcetera...

So by tracing boostrap.scss and opening it, I saw that it's importing a partial named _variables.scss, so on with the tour and here's _variable.scss

@import "ss-variables";

// Grays
// -------------------------
$black:                 #000 !default;
$grayDarker:            #222 !default;

( Note : I saw another boostrap.scss inside the /vendor/assets/stylesheets/bootstrap where _variables.ss is located) Aha! There's that little freak, "ss-variable"!! We're getting close on this wild partial chase. So I searched where ss-variables.scss is and found it on my lib/assets/stylesheets/ in the main app and it contains more scss variables.

So tracing them, I formulated this hypothesis that when trying to include bootstrap using stylesheet_link_tag on my engine, the engine doesn't see the dependent files that lies on the main app.

Bonus: I have a remarkable feeling that after this, the _ss_font css will be next. But that's for another story. Thanks.

From the looks of it, your problem might be caused by the asset_fingerprinting feature of the asset pipeline - basically appends all the production assets with an MD5 hash

--

Asset Fingerprinting

Essentially, if you're using the likes of Heroku (which requires your assets to be precompiled for them to be served), you will basically get a series of files in your public/assets folder like this:

|-public
|--assets
|---images
|---stylesheets
|---javascripts

The files contained in this folder, when precompiled, all have the fingerprinted filename. This means if you wanted to call one of these, you will need to use one of the ERB / SCSS preprocessors to access them:

#app/assets/stylesheets/application.css.scss
.style {
   background: asset_url("background.png");
}

This will reference the file, regardless of whether it's been precompiled (& fingerprinted ) or not. Although not exactly your issue, it is an important factor in what you're asking

--

Fix

I would suggest your issue is likely that you're referencing "static" CSS files, which really need to be dynamically referenced.

How do I include those assets?

You'll be best using @import like this:

#gem/app/assets/gem/widget.css.scss
@import "bootstrap.css" /* will probably need a relative path for this */
@import "other.css" /* again, will need a relative path */

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM