I've got an SCSS module with a whole lot of overridable !default variables, and I'm trying to make use of it in a project using the new @use rule instead of the to-be-deprecated @import. Overriding a large number of variables used to be pretty straightforward. As long as I imported my variables before importing the module they would take precedence over the !default values.
Now, if I try to @use the module in the global namespace like so:
$h1-font-size: 40px;
@use 'my-module' as *;
I get an error - SassError: This module and the new module both define a variable named "$h1-font-size".
Apparently the proper way to do this is to use the with keyword like so
@use 'my-module' with (
$h1-font-size: 40px
);
But now my $h1-font-size variable isn't available to other parts of my code. It's only scope is in overriding the value in the module. If I tried to assign it to something else, I'd get an Undefined variable error.
So that leaves me doing this
$h1-font-size: 40px;
@use 'my-module' with (
$h1-font-size: $h1-font-size
);
.foo {
font-size: $h1-font-size;
}
This is the exact effect I want - a variable that overrides my module and is still available for use elsewhere. However this syntax is cumbersome for passing a large number of overrides. If I want to pass say 30 overrides, I need 30 variable definitions and then 30 lines within the with block to explicitly pass in 30 values.
Update / Edit
The answer from @Miriam Suzanne below makes it apparent I have oversimplified my use case for the purpose of asking a question.
Our shop has a set of mixins and base styles we use on many projects and I have been attempting to turn them into a reusable module to reduce the copy/pasting. Something like Bootstrap, with a lot of overridable !default values. Very much a work in progress, but the module itself can be seen here: Derekstrap.
This module is being developed in tandem with the first project we're actually using this on. The !default values are all in the module, and I would like to override them in my project.
Right now I have code in my main.scss (the primary entry point for stylesheets) that looks like this.
$base-font-family: 'Raleway', Tacoma, sans-serif;
$base-line-height: 1.8;
@use '~@evanshunt/derekstrap/index' with (
$base-font-family: $base-font-family,
$base-line-height: $base-line-height
);
I like to structure my scss files pretty granularly so ideally those variables would actually live in another file, and also be available to other files in the project.
If I do something like the following, where both my variables file and the module have a $base-font-family variable defined, it compiles but by variables don't override the module.
@use 'variables' as *;
@use '~@evanshunt/derekstrap/index' as *;
I suspect at this point the answer is that I need to add @use and/or @forward statements to my variables file(s), but it's breaking my brain a bit to figure out if I'll be able to successfully override different parts of the module in different parts of my project code. The suggestion above of just one variables file is also a bit of a simplification. How important will the order of the @use statements in my main.scss become if I am modifying the same namespace across the files being @used?
I get the purpose of scoping and passing values explicitly but I'd love some sort of shorthand or trick to accomplish this without writing so much extra code. As mentioned in my Sass feature request ticket I was hoping for a simple shorthand for passing one context into another like:
@use 'variables' as variables;
@use 'module' with variables;
This doesn't seem possible and I'm wondering if I need to completely rethink the way I structure SCSS files to achieve what I want. What can I do here?