Avoid multiple imports of the same SCSS file with SASS (a different approach)
Imagine following, quite common scenario: We have a scss file defining standard font and text styles (font.scss
), another scss file which defines link styles (links.scss
) which uses variables and definitions of font.scss
and a third scss file which defines styles for form elements (form.scss
), which depends on fonts.scss
and links.scss
.
Managing these dependencies @import
ing all needed files in the same order in an app.scss
will work fine.
@import "font";
@import "links";
@import "form";
Unless you need some more flexibility and modularization and you want to allow to use the files separately, for example documenting them with SassDoc or StyleDocco.
Unfortunately it is not possible to use @import
within a function or mixin, otherwise it would be easy to write something like:
$imported-once-files: () !default;
@function import-once($name) {
$imported-once-files: $imported-once-files !global;
$module_index: index($imported-once-files, $name);
@if (($module_index == null) or ($module_index == false)) {
$imported-once-files: append($imported-once-files, $name);
@import $name;
}
}
There are some solution and articles out there, all encapsulating the whole content of a file:
- Foundation's solution using a mixin
@export
is explained here: http://4waisenkinder.de/blog/2014/03/06/import-once-in-sass-the-foundation-way/ - Another approach using
@if
is shown in the feature request for SASS: https://github.com/sass/sass/issues/156 - If you are using node-sass you can use this plugin: https://github.com/at-import/node-sass-import-once
- If you are using Compass, as of version 1.0 there is import-once already.
Neither solution worked for my use case. The first two don't work with mentioned StyleDocco. The third one needs node-sass version 3 at least and won't work with maven and frontend-maven-plugin using grunt-sass for now (grunt-sass uses node-sass 2.x).
Inspired by the first two solutions I created this workaround:
(see https://gist.github.com/paulwellnerbou/fd6e81bad2e6975d2805)
I use this function in mentioned forms.scss
:
@if not-imported("import-once-workaround") { @import "import-once-workaround"; }
@if not-imported("font") { @import "font"; }
@if not-imported("links") { @import "links"; }
Sure, this increases the code for a simple import significantly. But it keeps the files clean so that StyleDocco can generate it's documentation and I don't have to change the build infrastructure (depending on Compass 1.0+).
Waiting for SASS 4, where this will hopefully be solved (See heading "Import once"), as Chris points out in the last public comment of this feature request.