Error: Can't find stylesheet to import with @forward and @use variable precedence
0 reputation · 09 Dec 2024, 19:08 UTC
0 reputation · 09 Dec 2024, 19:08 UTC
Determine which variable value is ultimately used when a module forwards a variable that is also defined in the importing module, and whether the implementation honors the documented rule that @forward should not expose locally defined variables.
as aliasing.@use and @forward are employed in the same project.as keyword with @forward alter the shadowing behavior, especially when an alias conflicts with a local variable?@forward is involved, or does it change based on module resolution order?29775 reputation · 09 Dec 2024, 20:29 UTC
Yes: an unqualified variable reference always resolves to the variable defined in the current (importing) module, shadowing any forwarded variable of the same name. @forward only re-exports the forwarded module's public members into your module's API — it does not inject those names into your local scope. The as alias doesn't change shadowing; it only adds a namespace prefix to the forwarded members. And the "Can't find stylesheet to import" error is unchanged when @forward is involved — it comes from the same module-resolution step as @use.
In Dart Sass (your 1.71 test target), the module system follows the documented specification:
$color: red and also @forwards a module that defines $color: blue, a bare $color in your module is red. Downstream consumers who @use your module see the forwarded $color only if you did not redefine it — but note that if you do define it locally, that local variable is yours, not part of the forwarded API.@forward does not expose the forwarding module's locals. Only the forwarded module's own public members pass through. A variable you define in the forwarding file is not re-exported (unless you forward it again explicitly).as creates a prefix, not a scope change. With @forward 'tokens' as token-*, the forwarded variable is re-exported as $token-color. If you also define a local $token-color, the local one shadows the forwarded name for unqualified use — same rule, just a longer name. The alias does not give the forwarded variable priority.If you need the forwarded value despite a local same-named variable, namespace it with @use instead of relying on the forward:
// tokens.scss
$color: blue !default;
// theme.scss
@forward 'tokens';
@use 'tokens' as t;
$color: red;
// $color -> red (local wins)
// t.$color -> blue (explicit namespace)theme.scss with Dart Sass 1.71 (sass theme.scss out.css), and confirm a rule using $color emits red.$color definition and recompile — the unqualified reference now resolves to the forwarded value (or triggers an undefined-variable error if nothing forwards it, which itself proves forwarding was the source).@forward at a nonexistent file and compare the error text with a bad @use — both produce the standard "Error: Can't find stylesheet to import" because resolution happens identically for both directives.Ruby Sass reached end-of-life in 2019 and never fully implemented the module system (@use/@forward were introduced with Dart Sass). Any behavior you observe there — including whether the directives parse at all — should not be treated as evidence about the documented rules. Run these experiments in Dart Sass only, and treat Ruby Sass results as unrepresentative. If your Ruby Sass test appears to "work," it's likely falling back to legacy @import global semantics, where the last definition wins globally — a completely different rule set.
If you're seeing a different error message or precedence outcome in Dart Sass 1.71 than described above, the missing diagnostic is the exact file layout and the full compile command — load paths and the order of @use vs. @forward in the entry file are the usual culprits.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.