Skip to content
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

Allow optional @imports #779

Closed
imathis opened this issue May 30, 2013 · 15 comments
Closed

Allow optional @imports #779

imathis opened this issue May 30, 2013 · 15 comments
Labels
enhancement New feature or request under consideration The Sass team is debating whether to do this

Comments

@imathis
Copy link

imathis commented May 30, 2013

I believe it would be helpful to framework design and stylesheet modularity if there were a way to declare an @import which would fail gracefully if a file was not found.

Jumpt to the TL;DR

Syntax

To make it's behavior obvious this could be a flag !optional borrowing from the style of !default and !important. It might look like this:

@import "path/to/partial" !optional;

Use case

In Octopress I'm trying to make it easy for people to easily install themes and plugins (with their Sass assets) and I want it to be easy for users to customize these theme and plugin stylesheets. At the same time I want it to be possible for users to enjoy Octopress without installing any themes or plugins. As a result I have come up with this method for managing Sass.

Let's look at an Octopress stylesheet directory

/* A standard installation contains these two stylesheets */

site.scss         # Site import index (no not touch)
_style.scss       # Users add styles, import styles here

/* Created when a theme or plugin is installed */

plugins/
  widget-a/       # Plugins stylesheets are dir name spaced
    _style.scss   # Plugin Sass assets (imported automatically)

theme/
  _index.scss     # Theme import index (imported automatically)
  _settings.scss  # Sets Theme variables ($var: true !default;)
  core/           # Core styles (normalize, layout, color, etc)
  modules/        # Styles for components (article, sidebar, etc)

The root stylesheets site.scss uses optional imports and globbing to automatically import stylesheets from a theme or plugins.

@import "theme/index" !optional;
@import "plugins/*/style" !optional;

@import "style";             // Auto import user stylesheets

Here !optional imports would allow me to create a zero configuration install experience for end users. Users can install themes or plugins (or not) and they will automatically be imported. Also if I can reasonably expect them not to have any reason to change the site.scss file, making it easier for me to make changes to that file if needed.

Additionally if I wanted to allow users to easily override theme or plugin settings, I could change the site.scss like this:

@import "theme-settings" !optional;
@import "theme/index" !optional;
@import "plugin-settings" !optional;
@import "plugins/*/style" !optional;

@import "style";             // Auto import user stylesheets

This will allow a user to create a specific file to set default settings for a theme or plugin before it is imported. Without optional imports, a user must make changes to core files.

TL;DR

If imports can respect an !optional flag, frameworks like Octopress can create a framework which allows users to install new stylesheets without having to manage imports. Essentially this would allow zero-configuration installation for Sass stylesheets.

@MoOx
Copy link

MoOx commented May 30, 2013

👍

@nex3
Copy link
Contributor

nex3 commented May 30, 2013

In general, we're not planning on adding anything to the current @import syntax. We're planning on a large-scale redesign of importing, so adding functionality to the existing imports will be largely wasted effort.

I'm not sure this is something that's worth putting in the core Sass language. It seems like a reasonable use-case for defining a custom importer, though. #739 would also go part of the way towards obviating the need for this.

@nex3 nex3 closed this as completed May 30, 2013
@jlong
Copy link

jlong commented May 30, 2013

@imathis Can you restructure your theme folder so that you could do this with the Sass globbing plugin?

@import "theme/pages/**/*"
@import "plugins/*/style";
@import "theme/plugin-settings/**/*";
@import "theme/style"

Just a thought.

@chriseppstein
Copy link

I emailed a reply but I don't see it here:

@nex3 I'd like to discuss this with you. I don't see how optional imports are wasted effort with future development plans -- would like to understand why you think this is true.

This use case is an interesting one and I'd like to think about it more before discarding it out of hand.

@chriseppstein chriseppstein reopened this May 30, 2013
@nex3
Copy link
Contributor

nex3 commented May 30, 2013

I don't think it's worthwhile to add additional syntax to a construct we're planning on deprecating anyway.

@jslegers
Copy link

What about conditional loading within control directives and/or mixins?

The use case described by @imathis could also be implemented like this :

$partial : path/to/partial;
@if import-exists($partial) {
  @import $partial;
}

Not only does it solve the same problem a different way, but it would also allow one to do stuff like this :

@if not function-exists(str-replace) {
  @import '_str-replace';
}

@if $sassversion > 3.2 {
  @import '_new-sass';
} @else {
  @import '_old-sass';
}

$partial : path/to/partial;
@if import-exists($partial) {
  @import $partial;
}

I posted this as a separate issue, since my use case is a lot broader and the syntax is very different.
#1194

@nex3
Copy link
Contributor

nex3 commented Aug 28, 2015

I don't think this is going to make it into the new @import semantics. It's a great use-case for a custom importer, though.

@nex3 nex3 closed this as completed Aug 28, 2015
@yordis
Copy link

yordis commented Sep 7, 2015

👍 for see optional flag in @import

Look a very good use case https://github.com/Semantic-Org/Semantic-UI/blob/master/src/theme.less#L36

@tam5
Copy link

tam5 commented May 26, 2016

what is the status of this... is there a way to include a partial only if it exists?

@yordis
Copy link

yordis commented May 26, 2016

@tam5 I don't think that @nex3 will change her opinion. She closed it!

@entozoon
Copy link

He is a she.
A she that should re-open the issue, as optional imports would also let you catch the situation where an import file doesn't exist, in a useful way..
Say you're bowering in some sass junk but the dev forgot to run bower install.

You could have $packageIsLoaded: true in the imported file and then after the optional import, something like
@if $packageIsLoaded != true { @error "You haven't run bower install, you numpty!"; }

@migaber
Copy link

migaber commented Aug 29, 2016

Optional @import is really important

@jslegers
Copy link

Any update on this?

I've literally been waiting for optional imports to be implemented for >2 years now...

@tam5
Copy link

tam5 commented Sep 12, 2016

Until it gets implemented, I have come across two potential workarounds which may be helpful depending on the use case so I'll post them:

1 - Internal sass solution (files must exist):

Create a file app.scss which contains something like this:

$components: (
  foo,
  bar,
  baz
) !default;

@import "components/foo";
@import "components/bar";
@import "components/baz";

Then, in each of the "component" files you wrap all styles within something like this:

@if index($components, foo) {
  // styles
}

You have to include an import for each file and all files must exist, so this solution isn't all that much better than just deciding which @imports to include. However, @imathis's use case was primarily for a better user experience and a higher level of abstraction, which could be accomplished by playing around with this approach.

2 - Javascript... (More involved but full flexibility):

Very likely, your application will have to include some sort of build process, only part of which will be to process the sass, but which may also include gulp, webpack, etc. tasks. If you are using something like that, you can have the script that processes your css take care of the "optional" or logical imports. I know this may be annoying to configure, but it does give the greatest flexibility.

If you want an example to copy from have a look here.

@esr360
Copy link

esr360 commented Dec 16, 2016

I would really love this feature, seems essential long term, just a matter of when.

@sass sass locked and limited conversation to collaborators Dec 17, 2016
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request under consideration The Sass team is debating whether to do this
Projects
None yet
Development

No branches or pull requests