Sass @import directive when used in Rails engine c

2019-02-19 05:27发布

问题:

I was building a Rails engine that uses zurb-foundation's stylesheets, and kep hitting the same Sass::Syntax error. This seemed strange because I had followed the same procedure in a Rails application and it was worked on the first try. So I decided to zero in on the isse by starting two new rails projects--one application and one engine--and configure them to use foundation with a minimal amount of setup.

I started with 2 clean Rails 3.2.9 projects--one application and one engine --full and configured them both manually for foundations by adding foundation_and_overrides.scss and require-ing it in the CSS manifest.

I then creating a bare-bones controller so I'd have a page to load. For the application, loading that page and looking at the page source, I can see that foundation CSS was compiled correctly and loaded.

When I tried the same thing for the engine, I got this error:

Sass::SyntaxError in Main#index

Showing /<PLUGIN_PATH>/test/dummy/app/views/layouts/application.html.erb where line #5 raised:

File to import not found or unreadable: foundation/common/ratios.
Load path: /<PLUGIN_PATH>/test/dummy
  (in /<PLUGIN_PATH>/app/assets/stylesheets/example_plugin/foundation_and_overrides.scss)

(Note that the dummy app's CSS manifest is require-ing the plugin's CSS manifest, which is require-ing foundation_and_overrides.scss. The wiring is clearly not the issue because the error is raised from foundation_and_overrides.scss)

I tried this with several builds of Ruby-1.9.3 (p125, 194, p327, I think) with the same results.

It still didn't work when I added this line to test/dummy/config/application.rb:

config.assets.paths << "#{Foundation::Engine.root}/scss"

even though foundation/common/_ratios.scss exists at that path.

The issue may be with Sass, Sprockets, Compass, Foundation or Rails, so I don't know where to go from here.

I reported it as an issue with Foundation, but I'm not so convinced of that.

Has anyone seen this before?

回答1:

I found the answer in this Stackoverflow question

The issue is that a Rails engine's dummy app and a regular Rails app have slightly different config/application.rb files.

In a Rails app, you'll see this code towards the top:

if defined?(Bundler)
  # If you precompile assets before deploying to production, use this line
  Bundler.require(*Rails.groups(:assets => %w(development test)))
  # If you want your assets lazily compiled in production, use this line
  # Bundler.require(:default, :assets, Rails.env)
end

But in an engine dummy app, instead you see:

Bundler.require
require "<PLUGIN_NAME>"

In the Rails app, the first Bundler.require include all groups in the Gemfile but excludes :assets unless Rails.env is :development or :test The second Bundler.require includes :default--that is, anything in your Gemfile that's not in a group--as well as :assets and either :production, :development or :test

In a dummy app, none of this is necessary because 1) it's not meant to be used in production, and 2) test and development typically have similar dependency requirements. Since the :assets group is just a convenient way to apply dependencies to :test and :development but not to :production, in a dummy app it's the same as :default. So in a dummy app, nothing but :default is needed. Since Bundler.require is (Warning: Spoiler ahead) the same as Bundler.require(:default), the dummy app just uses Bundler.require. This means that anything in your Gemfile that's in a group will be ignored.

So the problem I had was that I was copy-and-pasting from a Rails app Gemfile into a Rails dummy app Gemfile, including group :assets do.... I removed the group line and everything worked!

ADDED later in the day on 11/29:

To clarify, the error I was seeing is because sass-rails wasn't included (since it was in the :assets group in my Gemfile), so instead of my assets being parsed as Sass, they were parsed as CSS. Since @import means something different to CSS than to Sass, whatever was parsing the CSS file was using a different implementation of @import and couldn't find the file.



回答2:

Hey guys I solved this problem, it took me like 5 hours to find out how to solve it (sorry about my english, is not my native language).

The normal installation of Foundation in Rails it didn't work for my Engine, so I did it manually:

I added this line to the application.html.erb: <meta name="viewport" content="width=device-width, initial-scale=1.0>

Add this line to your_engine/app/assets/javascripts/your_engine_name/application.js: //= require foundation

And this is how I Solved it:

Add this line to your_engine/app/assets/stylesheets/your_engine_name/application.css (NOTE: I didn't rename to application.scss): *= require your_engine_name/foundation_and_overrides

and also:

For Development, in the lines commented in the Gemfile, says "Declare any dependencies that are still in development here instead of in # your gemspec. These might include edge Rails or gems from your path or # Git. Remember to move these dependencies to your gemspec before releasing # your gem to rubygems.org." So I add the gems that I need, (Foundation, sass, compass, etc)

And tha's all, this is the way that I get my engine working with Foundation,