You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Originally I posted this here but I think this is a better forum for this appeal.
I've always wanted @import to give you more control over what gets imported and how. While it's very convenient to simply say @import 'blah'; and get everything in blah it has the drawback of making it very difficult to know where certain rules, mixins, etc. are coming from, especially when the stylebase gets heavy. This has given me a few headaches in the past as there can be some unwanted behavior (Ruby's require suffers from the same consequences).
Of course, there are a couple of ways to solve this.
An organized directory structure is one way to help you see where things are coming from (ie.@import "util/clearfix" meaning give me everything in the file util/_clearfix.scss). But there are two tradeoffs that I've encountered. First, you have to be very disciplined. The contents of _clearfix.scss should have no more than whatever is needed to implement clearfix. In this case maybe just a single mixin. Second, provided you are exercising good discipline, you can end up with an explosion of files. It's a hassle and basically amounts to a lot of babysitting.
Another way to avoid some confusion is to prefix mixin and variable names (ie. $foo-line-height or @mixin foo-button). This sort of pattern appears in plenty of other languages with relaxed import mechanisms where stuff is just being dumped in to some global namespace. While it can work, it's really just a cheap hack. To make it a really good hack you'd have to combine it with the solution I mentioned above.
TL;DR you have to be very organized and defensive. I contend this does nothing more than add unnecessary complexity and cognitive load.
So what's the idea? First, let's consider the problem with an example. I have three files style.scss, _foo.scss, and _bar.scss:
That sucks. The contents of _bar.scss are basically overriding the contents of _foo.scss. Surely we can do better. What if we extended @import with just a tiny bit of optional syntax? Consider the following proposals:
OK. But what if I want to rename, or exclude identifiers?
// style.scss@import"foo";
@import"bar" (exclude: weeble) and (rename: quuxbar-quux);
h1 {
@includequux; // This is foo/quux.@includeweeble; // This is foo/weeble.
}
h2 {
@includebar-quux; // This is bar/quux.
}
The (exclude: ident [, ident]*) clause tells Sass to import everything except the identifiers listed. The (rename: l-ident r-ident [, l-ident r-ident]*) clause takes a comma separated list of identifier pairs and tells Sass to import the identifiers listed but rename the first identifier of the pair to the second. We use and to separate clauses.
This is extremely nice. I know where code is coming from because it's documented in the import. I have control over the naming when I import which allows me to resolve potential conflicts and avoid unwanted behavior. The additional syntax doesn't break existing code and it looks syntactically similar to other @ prefixed syntax in CSS. Finally, it eliminates most of the defensive programming techniques I mentioned above.
FWIW, I understand that implementing this correctly might be a bit involved and could take some time. There's a lot to think about. But the behavior of @import has been the single biggest pain point for me when using Sass. I know in the past it was proposed to incorporate the Less style namespaces for this sort of thing, but was ultimately rejected for understandable reasons. This however, should it be considered, would be a vastly cleaner approach to handling imports than Less or what's currently available in Sass.
Please take sometime to consider the idea.
The text was updated successfully, but these errors were encountered:
We're definitely interested in improving the semantics of @import (or rather, creating a new @import-like directives with better semantics). There are a number of use cases we're considering, the ones you bring up here among them. I don't think our ultimate solution will end up looking exactly like this, but hopefully it will address the same problems with the current syntax, and others as well.
In any case, the new import syntax is tracked by #353.
Originally I posted this here but I think this is a better forum for this appeal.
I've always wanted
@import
to give you more control over what gets imported and how. While it's very convenient to simply say@import 'blah';
and get everything inblah
it has the drawback of making it very difficult to know where certain rules, mixins, etc. are coming from, especially when the stylebase gets heavy. This has given me a few headaches in the past as there can be some unwanted behavior (Ruby'srequire
suffers from the same consequences).Of course, there are a couple of ways to solve this.
An organized directory structure is one way to help you see where things are coming from (ie.
@import "util/clearfix"
meaning give me everything in the fileutil/_clearfix.scss
). But there are two tradeoffs that I've encountered. First, you have to be very disciplined. The contents of_clearfix.scss
should have no more than whatever is needed to implementclearfix
. In this case maybe just a single mixin. Second, provided you are exercising good discipline, you can end up with an explosion of files. It's a hassle and basically amounts to a lot of babysitting.Another way to avoid some confusion is to prefix mixin and variable names (ie.
$foo-line-height
or@mixin foo-button
). This sort of pattern appears in plenty of other languages with relaxed import mechanisms where stuff is just being dumped in to some global namespace. While it can work, it's really just a cheap hack. To make it a really good hack you'd have to combine it with the solution I mentioned above.TL;DR you have to be very organized and defensive. I contend this does nothing more than add unnecessary complexity and cognitive load.
So what's the idea? First, let's consider the problem with an example. I have three files
style.scss
,_foo.scss
, and_bar.scss
:From the command line I run
sass style.scss
and getThat sucks. The contents of
_bar.scss
are basically overriding the contents of_foo.scss
. Surely we can do better. What if we extended@import
with just a tiny bit of optional syntax? Consider the following proposals:The
(only: ident [, ident]*)
clause tells Sass to import the only the identifiers listed.From the command line I run
sass style.scss
and getOK. But what if I want to rename, or exclude identifiers?
The
(exclude: ident [, ident]*)
clause tells Sass to import everything except the identifiers listed. The(rename: l-ident r-ident [, l-ident r-ident]*)
clause takes a comma separated list of identifier pairs and tells Sass to import the identifiers listed but rename the first identifier of the pair to the second. We useand
to separate clauses.We run
sass style.scss
and getThis is extremely nice. I know where code is coming from because it's documented in the import. I have control over the naming when I import which allows me to resolve potential conflicts and avoid unwanted behavior. The additional syntax doesn't break existing code and it looks syntactically similar to other
@
prefixed syntax in CSS. Finally, it eliminates most of the defensive programming techniques I mentioned above.FWIW, I understand that implementing this correctly might be a bit involved and could take some time. There's a lot to think about. But the behavior of
@import
has been the single biggest pain point for me when using Sass. I know in the past it was proposed to incorporate the Less style namespaces for this sort of thing, but was ultimately rejected for understandable reasons. This however, should it be considered, would be a vastly cleaner approach to handling imports than Less or what's currently available in Sass.Please take sometime to consider the idea.
The text was updated successfully, but these errors were encountered: