What is the correct method for setting up a SASS module "library" with @use to allow users to override library variables?

Viewed 80

With the move to @use and explicitly local namespaced variables, it seems that in order to override an Sass "library's" variables it ends up leading to somewhat unsightly code. Is this expected, or am I missing something, being relatively new to Sass?

Previously, one threw caution to the wind and simply created global variables. (And, yes, I know @import is still around for another couple of years, but I'm interested in future-proofing my projects.)

@import "_vars";
@import "vendor/cool_library";

Now, since @import is being deprecated we should move to @use.

@use "_vars";
@use "vendor/cool_library";

The only way I've seen in my searches to get variables overridden in the "vendor/cool_library" code is to either add @use "../_vars" to the cool_library file, or use:

@use "vendor/cool_library" with ($varname: "var_data");

Adding my vars file to the library is a no-go, since it would make it a pain to keep a clean submodule repo. So that's out, which leaves the "with()" option as the only apparent method?

But, with some libraries, that could lead to something like this:

@use "vendor/cool_library" with (
        $line-height: 2.4rem,
        $global-radius: .2rem,
        $border-color: #bbb,
        $font-sans-serif: "Roboto", Helvetica, Arial, sans-serif !default,
        $font-serif: "Merriweather", Georgia, "Times New Roman", Times, serif,
        $font-monospace: Menlo, Monaco, Consolas, "Courier New", monospace,
        $font-base: $font-sans-serif,
        $font-color: #222222,
        $font-size: 22px ,
        $font-size--lg: 48px, 
        $font-size--md: 16px, 
        $font-size--sm: 14px, 
        $font-size--xs: 10px,
        . . . . And on and on... however many variables you need to override...
    );

A variation on that is to call @use "_vars" before that but that only gains you the ability to set those with() variables with content from _vars and manage the variable content in the _vars file. The @use line would still look a mess as it does above.

I had hoped that since with() wanted a map, that I could just feed it a variable comprised of a map, but didn't seem to work when I tried it...

Alternatively, mixins could be used, but this would lead to reconstructing libraries like web frameworks in your own Sass files, which is not appealing.

So... am I missing something obvious (really hoping I am)? Or is this really the new way with @use modules?

1 Answers

Unfortunately it seems like the with() method you point to is the only way to go. I first tried to @use just the _variables.scss file and then set up my modified variables in the with() method, and then import the rest of the scss project below that, hoping that the variables would be taken into account. But that didn't work although it actually did compile.

Only by @using the entry point file in node_modules/cool_css_framework/main.scss I was able to modify the variables, like you indicated:

    @use './../../../node_modules/cool_css/main.scss' with (
      $link-color: #ffe88d,
      $link-color-hover: #fff0b4,
      $container-max-width: 1600px,

      $etc ...
    );

For this to work the original $variables have to be set with the !default flag:

$link-color: green !default;

Related