Ambiguity in Sass module privacy: relying on naming conventions vs explicit @forward show lists
0 reputation · 15 May 2020, 19:52 UTC
0 reputation · 15 May 2020, 19:52 UTC
When using the Sass module system with @use, members are public by default unless they begin with a hyphen or underscore. Teams can also control exposure through a central entrypoint that uses @forward with explicit show lists to re‑export only intended members. The project must decide whether to rely solely on the naming‑based privacy mechanism, to adopt the explicit show‑list approach, or to combine both, considering factors such as maintainability, tooling support, and the risk of accidental public exposure.
Which strategy provides the clearest guarantee that internal helpers remain inaccessible to downstream stylesheets while keeping the public API surface minimal and easy to audit?
30275 reputation · 16 May 2020, 04:58 UTC
The clearest guarantee that internal helpers remain inaccessible while keeping a minimal public API is to combine both naming-based privacy and explicit @@forward show lists. While naming conventions provide immediate, local signals to developers, explicit show lists act as the final programmatic gatekeeper for the public interface.
| Mechanism | Scope | Benefit | Risk |
|---|---|---|---|
| Naming (hyphen/underscore) | Implicit/Local | Visual signal | Accidental exposure if forgotten |
| @forward show/hide | Explicit/Boundary | Strict whitelisting | Maintenance overhead |
To maximize encapsulation in Dart Sass, follow this dual-layer approach:
@use.index.scss) that uses @forward with explicit show lists. This ensures only intended members are exposed to consumers.// colors.scss
$-internal-palette: #ff0000; // Private
$primary-color: #0000ff; // Public
// index.scss
@forward 'colors' show $primary-color;
Relying solely on naming conventions is risky because a single omitted hyphen silently exposes a helper to the entire downstream project. Conversely, relying solely on @forward lists can be tedious to audit. By combining them, you create a "defense-in-depth" architecture: the hyphen prevents accidental usage, and the show list prevents accidental exposure.
To verify your API surface, attempt to access a private member from a downstream stylesheet:
@use 'library';
.test { color: library.$internal-palette; } // Should trigger an error
Diagnostic Detail: Are you using a centralized index.scss for your library, or are downstream files @useing component files directly? If the latter, @forward lists are bypassed, and you must rely entirely on naming conventions.
Use comments to ask for clarification. Post a solution as an answer.
3,300 reputation · 15 May 2020, 21:38 UTC
When a Sass identifier begins with - or _, it is hidden from the module’s @use namespace, but it is still considered a public member for @forward unless you explicitly hide it. In contrast, a file whose name starts with _ is a partial; it is not compiled to CSS on its own, yet its contents can still be forwarded. Therefore, to guarantee a helper never appears in downstream stylesheets you must either prefix the identifier with - or _ and use @forward … hide (or rely on an explicit show list).