New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request: @import-once #156

Closed
seanofw opened this Issue Aug 15, 2011 · 10 comments

Comments

Projects
None yet
8 participants
@seanofw

seanofw commented Aug 15, 2011

I've used Sass on a number of projects now with great success, and finally convinced my company to use it on our flagship product --- a massive web application --- to make our 120,000 lines of CSS more manageable.

In doing so, I've found that there's a feature that would make for a really nice addition: The ability to mark some files with an "@import-once" directive, which causes that file to be imported only once no matter how many different other files import it.

Consider this scenario:

  • _SharedBaseStuff.scss has a bunch of base definitions.
  • _FooWidget.scss imports _SharedBaseStuff.scss
  • _BarWidget.scss imports _SharedBaseStuff.scss
  • YourPage.scss imports _FooWidget.scss
  • MyPage.scss imports _BarWidget.scss
  • TheirPage.scss imports both _FooWidget.scss and _BarWidget.scss

Without doing anything else, TheirPage.css will end up with two copies of any CSS found in _SharedBaseStuff.scss, which is undesirable. It'd be far better if inside _SharedBaseStuff.scss, you could just declare @import-once; at the top, which would ensure you only get the first copy in the output no matter how many times it's imported. (By definition, @import-once could not be appear inside an imported file that is nested within another selector or mixin; it could only appear at the root.)

(Yes, this is a real scenario on our huge site. In fact, our real-world scenarios are far uglier, with some .scss files able to be imported dozens of times or more by a single page's stylesheet.)

Currently, a little function like this can be used to implement a workaround:

$imported-once-files: ();

@function import-once($name) {
    @if index($imported-once-files, $name) {
        @return false;
    }
    $imported-once-files: append($imported-once-files, $name);
    @return true;
}

And then used like this:

@if import-once("_SharedBaseStuff.scss") {

    ...declare stuff that will only be imported once...

}

That works, but for large filesets with lots of imports, it's inefficient. Having a simple global @import-once; directive would make this much simpler.

@nex3

This comment has been minimized.

Show comment
Hide comment
@nex3

nex3 Aug 15, 2011

Contributor

This is something we'll consider for the upcoming re-envisioning of the @import functionality.

Contributor

nex3 commented Aug 15, 2011

This is something we'll consider for the upcoming re-envisioning of the @import functionality.

@chriseppstein

This comment has been minimized.

Show comment
Hide comment
@chriseppstein

chriseppstein Aug 16, 2011

Member

Duplicate of #139

Member

chriseppstein commented Aug 16, 2011

Duplicate of #139

@chriseppstein

This comment has been minimized.

Show comment
Hide comment
@chriseppstein

chriseppstein Aug 16, 2011

Member

BTW, that @if stuff is pretty clever :) It's pretty much how C solves this problem.

Member

chriseppstein commented Aug 16, 2011

BTW, that @if stuff is pretty clever :) It's pretty much how C solves this problem.

@seanofw

This comment has been minimized.

Show comment
Hide comment
@seanofw

seanofw Aug 17, 2011

Yah, I've done a lot of C coding, give or take a million lines. :-)

For the record, I think it's more meaningful to have the once-ness determined by the importee rather than the importer --- by the file that's being imported rather than by the file that's importing it. @import-once is a safe construct; no matter who imports that file, they can't screw it up, because it's impossible to import that file more than once; the caller can't make a mistake. But the suggestion in the other thread (which I missed when I searched for this topic), where you might add @require --- that suggestion allows the caller to decide whether the file gets imported once or many times, which is dangerous: If any one caller forgets and uses @import instead of @require, the imported code may end up imported more than once because of it. I've been bit by that in other languages, and I'd rather not see the same problem repeated in Sass.

seanofw commented Aug 17, 2011

Yah, I've done a lot of C coding, give or take a million lines. :-)

For the record, I think it's more meaningful to have the once-ness determined by the importee rather than the importer --- by the file that's being imported rather than by the file that's importing it. @import-once is a safe construct; no matter who imports that file, they can't screw it up, because it's impossible to import that file more than once; the caller can't make a mistake. But the suggestion in the other thread (which I missed when I searched for this topic), where you might add @require --- that suggestion allows the caller to decide whether the file gets imported once or many times, which is dangerous: If any one caller forgets and uses @import instead of @require, the imported code may end up imported more than once because of it. I've been bit by that in other languages, and I'd rather not see the same problem repeated in Sass.

@davidrivers

This comment has been minimized.

Show comment
Hide comment
@davidrivers

davidrivers Jun 8, 2012

+1 for native support. I just had a specificity-override scenario where I had to implement the import-once @function above to work around it :(

davidrivers commented Jun 8, 2012

+1 for native support. I just had a specificity-override scenario where I had to implement the import-once @function above to work around it :(

@thejase

This comment has been minimized.

Show comment
Hide comment
@thejase

thejase Dec 18, 2012

+1 for native support. I'd like to use the above workaround for magic sprites, but the "@include" portion cannot live inside an @if.

thejase commented Dec 18, 2012

+1 for native support. I'd like to use the above workaround for magic sprites, but the "@include" portion cannot live inside an @if.

@chriseppstein

This comment has been minimized.

Show comment
Hide comment
Member

chriseppstein commented Dec 6, 2013

@jlong

This comment has been minimized.

Show comment
Hide comment
@jlong

jlong Feb 1, 2014

@chriseppstein Did this get merged into 3.3 or is it still just a plugin?

jlong commented Feb 1, 2014

@chriseppstein Did this get merged into 3.3 or is it still just a plugin?

@cseeger

This comment has been minimized.

Show comment
Hide comment
@cseeger

cseeger Feb 4, 2014

@jlong, it looks like this will be part of the 4.0 release.

cseeger commented Feb 4, 2014

@jlong, it looks like this will be part of the 4.0 release.

@emilypriddy

This comment has been minimized.

Show comment
Hide comment
@emilypriddy

emilypriddy Mar 12, 2014

That will be a great addition!

emilypriddy commented Mar 12, 2014

That will be a great addition!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.