There is no module with the namespace "v". - color: v.$mainHeaderColor;
Your receiving the error when compiling main.scss because the _layout.scss partial file doesn't know about the namespace "v" and wasn't able to load the members like $mainHeaderColor from the _variables.scss module. This happens because _layout.scss doesn't have a @use rule loading the members from "variables", therefore it can't access variables defined in that module.
A "quick" fix would be to introduce a @use rule in your _layout.scss file to load the variables from _variables.scss like this:
@use "./variables" as v;
/* _layout.scss */
h1 {
color: v.$mainHeaderColor;
}
Now there really isn't a need to use @forward with your current structure as its only two partial files being loaded into main.scss. If you want to use @forward I'd recommend reading further and setting up directories with index files.
To update your main file, this is how loading the files with @use at-rules into main.scss would look:
@use 'variables' as v;
@use 'layout';
/* main.scss */
/* Use the loaded members from '_variables.scss' inside the main file */
.demo {
color: v.$mainHeadColor;
}
Using @use rules along with @forward and index files
With the @import at-rule slowly being phased out of the main implementation of Sass, (dart-sass). It's time for us to adopt @use rules and learn how to utilize the cool features like index files with @forward and setting custom namespaces for loaded modules.
Since @import at-rules made everything globally accessible, this is where I've seen most of the confusion around usage of @use come into play. We have to make sure all files have appropriate knowledge of variables, mixins, functions etc if they aren't defined in the same partial or file.
If you have a main.scss Sass file that is going to be compiled with two (or more) imported partial files. The best way to utilize @use and @forward rules is by creating a directory at the same level as your main.scss file (or elsewhere just use the correct path) and create an index file, _index.scss to load the entire directory of partials with a single @use rule.
Note: All @use at-rules must be placed at the top of the file.
This index file will be where you place your @forward rules, using @forward "<url>"; for each partial you want to load into the index file. Think of it as one big module that you can load elsewhere with a single @use rule in your main.scss file, thus giving you access to all of the partial files loaded into that index file within the /partials directory.
- main.scss
- partials/
- _index.scss
- _variables.scss
- _layout.scss
...
Going along with the example, lets say your _variables.scss partial file looked like this and wasn't relying on any other files:
$mainHeaderColor: #222;
$someOtherVar: #f06;
and if the _layout.scss partial wanted to use variables defined in _variables.scss, we would have to include a @use rule to let _layout.scss "know" about the loaded members.
@use "./variables" as v;
/* _layout.scss */
h1 {
/* now this works as expected */
color: v.$mainHeaderColor;
}
If you didn't want to define a namespace when loading with @use, simply write @use "<url>" as <namespace>; where the namespace being an asterisk * signals that a namespace won't be defined so you can use it like color: $mainHeaderColor instead of v.$mainHeaderColor. Note, this can leading to naming conflicts if your not careful.
Now to load these partials into the main.scss file which will be compiled, you could either use two separate @use rules for the _layout.scss and _variables.scss partials or create an index file (_index.scss) and load the /partials directory with a single @use at-rule giving you access to all the partials in the directory.
@forward "./variables";
@forward "./layout";
/* partials/_index.scss */
Voila! Now all that is left is to load the /partials directory into the main.scss file to be compiled and maybe used later on. The _layout.scss partial is loaded into main.scss through our single @use rule and we also have access to _variables.scss variables or any other partial file that was forwarded in the index file.
@use "./partials" as *;
/* main.scss */
h2 {
color: $mainHeaderColor;
background: $someOtherVar;
}
If you had a directory of mixins like ./mixins, then you would follow the same workflow of placing all partial files inside the /mixins directory and then create an _index.scss file to load the partials with @forward rules. To finally load the directory with a single @use rule giving you access to all of the partials loaded in a specific directory through an index file. I used the /partials directory as a "starting" point but it would make more sense to create a directory /vars, /mixins etc and place files in their respective directories for better structure/organization.