Victor Costan
2011-Jul-01 21:16 UTC
Rails 3.1 asset pipeline and SCSS modules with inter-dependencies
Dear core team, I have a scenario that I think is important for developing apps with DRY, modular CSS, and I can''t figure out how to make it work with the asset pipeline. I hope this provides useful feedback on what I think is a shortcoming in the pipeline design. The simplified scenario: I have a common.scss, with SCSS shared by multiple applications. However, I''d like to override some variables in common.scss in each application. For example, I have a $color variable that sets the general hue of the application, and all the colors used are computed based on that variable. I put all those variables in a _vars.scss partial that is @imported by common.scss. An application also has its'' own SCSS, in special.scss. The application-specific SCSS also uses the variables in _vars.scss, to keep things DRY. In Rails 3.0, I had a generator that copied the following structure to /public/stylesheets: /common/_vars.scss /common/common.scss -- @imports _vars.scss /special.scss -- @imports _vars.scss For Rails 3.1, I would like to keep common.scss in /app/assets in an engine gem, and generate _vars.scss inside the application. However, I''m not sure what''s the best place to put _vars.scss, and how to get it @imported in common.scss. I don''t think _vars.scss belongs in /app/assets, because I don''t want the //= require_tree to pick it up, but I really don''t know where it should go, or what API I should use to compute its path. DHH said, in his keynote, that he''s been using the pipeline mostly for JavaScript. SCSS is different, because a compiled .scss doesn''t have all the information in the original file -- the .css output doesn''t have mixin and variable information. Maybe we need a helper for @importing? Thank you for your help in advance, Victor -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com. To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.
Chris Eppstein
2011-Jul-01 22:01 UTC
Re: Rails 3.1 asset pipeline and SCSS modules with inter-dependencies
You should definitely keep _all_ your sass stylesheets in app/assets/stylesheets. Name your partials beginning with an underscore and use ".css.scss" as the extension. Import files by omitting leading underscores and extensions. IMO, Sprockets needs to add partial support, such files should return a 404 if they are accessed directly by url. But this is not a big deal. Don''t use require_tree. Instead use the glob importing that sass-rails provides in those places where it makes sense. The Sass @import directive allows sass files to share cache more efficiently and makes the variables, mixins, etc from imported files accessible to later imports and the current file. Sass-rails provides full glob support relative to the current file. So you can `@import "**/*"` if you want the same behavior of require_tree, but you can also just do `@import "*/*"` if you only want one level of imports or you can do `@import "library/*"` if you only want to import from one directory. Lastly, Sass users are accustomed to any non-partial getting written out to a css file, but in rails it seems you have to explicitly enumerate files to be precompiled by adding them to config.assets.precompile explicitly. I think rails should adopt the Sass convention of automatically precompiling all stylesheets that are not partials. Chris On Fri, Jul 1, 2011 at 2:16 PM, Victor Costan <costan@gmail.com> wrote:> Dear core team, > > I have a scenario that I think is important for developing apps with > DRY, modular CSS, and I can''t figure out how to make it work with the > asset pipeline. I hope this provides useful feedback on what I think > is a shortcoming in the pipeline design. > > The simplified scenario: I have a common.scss, with SCSS shared by > multiple applications. However, I''d like to override some variables in > common.scss in each application. For example, I have a $color variable > that sets the general hue of the application, and all the colors used > are computed based on that variable. I put all those variables in a > _vars.scss partial that is @imported by common.scss. An application > also has its'' own SCSS, in special.scss. The application-specific SCSS > also uses the variables in _vars.scss, to keep things DRY. > > In Rails 3.0, I had a generator that copied the following structure to > /public/stylesheets: > /common/_vars.scss > /common/common.scss -- @imports _vars.scss > /special.scss -- @imports _vars.scss > > For Rails 3.1, I would like to keep common.scss in /app/assets in an > engine gem, and generate _vars.scss inside the application. However, > I''m not sure what''s the best place to put _vars.scss, and how to get > it @imported in common.scss. I don''t think _vars.scss belongs in > /app/assets, because I don''t want the //= require_tree to pick it up, > but I really don''t know where it should go, or what API I should use > to compute its path. > > DHH said, in his keynote, that he''s been using the pipeline mostly for > JavaScript. SCSS is different, because a compiled .scss doesn''t have > all the information in the original file -- the .css output doesn''t > have mixin and variable information. Maybe we need a helper for > @importing? > > Thank you for your help in advance, > Victor > > -- > You received this message because you are subscribed to the Google Groups > "Ruby on Rails: Core" group. > To post to this group, send email to rubyonrails-core@googlegroups.com. > To unsubscribe from this group, send email to > rubyonrails-core+unsubscribe@googlegroups.com. > For more options, visit this group at > http://groups.google.com/group/rubyonrails-core?hl=en. > >-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com. To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.
Victor Costan
2011-Jul-03 04:27 UTC
Re: Rails 3.1 asset pipeline and SCSS modules with inter-dependencies
Thank you very much, for your detailed response, Chris! I didn''t know @import can take globs, I can definitely use that to clean some things up! Just to make sure I understand, are you suggesting that my plugin''s generator should copy common.scss into app/assets/stylesheets, and then use @import with a glob somewhere to pull everything in? I was hoping I can have common.scss into a plugin''s app/assets/stylesheets directory, which could be updated independently of the application, just like jquery-rails updates its JavaScript files. However, if I do that, @importing with a glob won''t work, because the plugin''s app/assets/stylesheets would be somewhere in my gems directory. I''m sorry for being slow in understanding your answer, and I''m grateful for any further insight you can share! Victor On Fri, Jul 1, 2011 at 6:01 PM, Chris Eppstein <chris@eppsteins.net> wrote:> You should definitely keep _all_ your sass stylesheets in > app/assets/stylesheets. > Name your partials beginning with an underscore and use ".css.scss" as the > extension. Import files by omitting leading underscores and extensions. > IMO, Sprockets needs to add partial support, such files should return a 404 > if they are accessed directly by url. But this is not a big deal. > Don''t use require_tree. Instead use the glob importing that sass-rails > provides in those places where it makes sense. The Sass @import directive > allows sass files to share cache more efficiently and makes the variables, > mixins, etc from imported files accessible to later imports and the current > file. > Sass-rails provides full glob support relative to the current file. So you > can `@import "**/*"` if you want the same behavior of require_tree, but you > can also just do `@import "*/*"` if you only want one level of imports or > you can do `@import "library/*"` if you only want to import from one > directory. > Lastly, Sass users are accustomed to any non-partial getting written out to > a css file, but in rails it seems you have to explicitly enumerate files to > be precompiled by adding them to config.assets.precompile explicitly. I > think rails should adopt the Sass convention of automatically precompiling > all stylesheets that are not partials. > Chris > On Fri, Jul 1, 2011 at 2:16 PM, Victor Costan <costan@gmail.com> wrote: >> >> Dear core team, >> >> I have a scenario that I think is important for developing apps with >> DRY, modular CSS, and I can''t figure out how to make it work with the >> asset pipeline. I hope this provides useful feedback on what I think >> is a shortcoming in the pipeline design. >> >> The simplified scenario: I have a common.scss, with SCSS shared by >> multiple applications. However, I''d like to override some variables in >> common.scss in each application. For example, I have a $color variable >> that sets the general hue of the application, and all the colors used >> are computed based on that variable. I put all those variables in a >> _vars.scss partial that is @imported by common.scss. An application >> also has its'' own SCSS, in special.scss. The application-specific SCSS >> also uses the variables in _vars.scss, to keep things DRY. >> >> In Rails 3.0, I had a generator that copied the following structure to >> /public/stylesheets: >> /common/_vars.scss >> /common/common.scss -- @imports _vars.scss >> /special.scss -- @imports _vars.scss >> >> For Rails 3.1, I would like to keep common.scss in /app/assets in an >> engine gem, and generate _vars.scss inside the application. However, >> I''m not sure what''s the best place to put _vars.scss, and how to get >> it @imported in common.scss. I don''t think _vars.scss belongs in >> /app/assets, because I don''t want the //= require_tree to pick it up, >> but I really don''t know where it should go, or what API I should use >> to compute its path. >> >> DHH said, in his keynote, that he''s been using the pipeline mostly for >> JavaScript. SCSS is different, because a compiled .scss doesn''t have >> all the information in the original file -- the .css output doesn''t >> have mixin and variable information. Maybe we need a helper for >> @importing? >> >> Thank you for your help in advance, >> Victor >> >> -- >> You received this message because you are subscribed to the Google Groups >> "Ruby on Rails: Core" group. >> To post to this group, send email to rubyonrails-core@googlegroups.com. >> To unsubscribe from this group, send email to >> rubyonrails-core+unsubscribe@googlegroups.com. >> For more options, visit this group at >> http://groups.google.com/group/rubyonrails-core?hl=en. >> > > -- > You received this message because you are subscribed to the Google Groups > "Ruby on Rails: Core" group. > To post to this group, send email to rubyonrails-core@googlegroups.com. > To unsubscribe from this group, send email to > rubyonrails-core+unsubscribe@googlegroups.com. > For more options, visit this group at > http://groups.google.com/group/rubyonrails-core?hl=en. >-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com. To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.
Chris Eppstein
2011-Jul-03 04:45 UTC
Re: Rails 3.1 asset pipeline and SCSS modules with inter-dependencies
On Sat, Jul 2, 2011 at 9:27 PM, Victor Costan <costan@gmail.com> wrote:> Thank you very much, for your detailed response, Chris! I didn''t know > @import can take globs, I can definitely use that to clean some things > up! >It''s a feature that''s only available via sass-rails or if they install my sass-globbing plugin (https://github.com/chriseppstein/sass-globbing).> Just to make sure I understand, are you suggesting that my plugin''s > generator should copy common.scss into app/assets/stylesheets, and > then use @import with a glob somewhere to pull everything in? >I was suggesting that you shouldn''t put them in public anymore. Best to think of public like tmp.> I was hoping I can have common.scss into a plugin''s > app/assets/stylesheets directory, which could be updated independently > of the application, just like jquery-rails updates its JavaScript > files. However, if I do that, @importing with a glob won''t work, > because the plugin''s app/assets/stylesheets would be somewhere in my > gems directory. >You can add your libraries to the sass load path and import them without globbing. This is basically what compass does. You can add to the sass load paths in a railtie: config.sass.load_paths << "/path/to/my/gems/stylesheets"> I''m sorry for being slow in understanding your answer, and I''m > grateful for any further insight you can share! >No problem. Hit me up in IRC if you need more clarification. -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com. To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.